├── .gitignore
├── LICENSE
├── README.md
├── build.gradle
├── demo
├── .gitignore
├── MagicHeaderViewPager_demo.jks
├── apk
│ └── MagicHeaderViewPager_demo_1.0.apk
├── build.gradle
├── gradle.properties
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── culiu
│ │ └── mhvp
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── culiu
│ │ └── mhvp
│ │ └── demo
│ │ ├── APP.java
│ │ ├── AbsDemoFragment.java
│ │ ├── DemoActivity.java
│ │ ├── DemoConfig.java
│ │ ├── DemoGridFragment.java
│ │ ├── DemoListFragment.java
│ │ ├── DemoPagerAdapter.java
│ │ ├── DemoPullToRefreshGridFragment.java
│ │ ├── DemoPullToRefreshListFragment.java
│ │ ├── DemoPullToRefreshScrollFragment.java
│ │ ├── DemoScrollFragment.java
│ │ ├── RandomPic.java
│ │ └── WelcomeActivity.java
│ └── res
│ ├── drawable-xxhdpi
│ ├── bg_1.jpg
│ ├── bg_10.jpg
│ ├── bg_11.jpg
│ ├── bg_12.jpg
│ ├── bg_13.jpg
│ ├── bg_2.jpg
│ ├── bg_3.jpg
│ ├── bg_4.jpg
│ ├── bg_5.jpg
│ ├── bg_6.jpg
│ ├── bg_7.jpg
│ ├── bg_8.jpg
│ └── bg_9.jpg
│ ├── drawable
│ ├── bg_btn_welcome.xml
│ └── ptr_loading_bg.png
│ ├── layout
│ ├── activity_mhvp_demo.xml
│ ├── activity_welcome.xml
│ ├── fragment_list.xml
│ ├── fragment_pulltorefresh_list.xml
│ ├── fragment_pulltorefresh_scrollview.xml
│ ├── fragment_scrollview.xml
│ ├── header_custom_layout.xml
│ ├── item_grid_fragment.xml
│ ├── item_list_fragment.xml
│ ├── layout_tabs1.xml
│ └── pull_to_refresh_header_vertical.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── doc
└── README.md
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
├── mhvp-core
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── culiu
│ │ └── mhvp
│ │ └── core
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── culiu
│ │ └── mhvp
│ │ └── core
│ │ ├── InnerListView.java
│ │ ├── InnerScrollView.java
│ │ ├── InnerScroller.java
│ │ ├── InnerScrollerContainer.java
│ │ ├── MagicHeaderUtils.java
│ │ ├── MagicHeaderViewPager.java
│ │ ├── OuterPagerAdapter.java
│ │ ├── OuterScroller.java
│ │ ├── ScrollableViewPager.java
│ │ ├── layout
│ │ ├── SizeSensitiveLinearLayout.java
│ │ └── TranslatableLinearLayout.java
│ │ ├── specialview
│ │ └── InnerSpecialViewHelper.java
│ │ ├── tabs
│ │ ├── GridViewWithHeaderBaseAdapter.java
│ │ └── com
│ │ │ └── astuetz
│ │ │ └── PagerSlidingTabStrip.java
│ │ └── util
│ │ └── IntegerVariable.java
│ └── res
│ ├── drawable
│ └── background_tab.xml
│ ├── layout
│ └── mhvp_layout.xml
│ └── values
│ ├── colors.xml
│ ├── ids.xml
│ ├── psts_attr.xml
│ └── strings.xml
├── mhvp-integrated-ptr
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── culiu
│ │ └── mhvp
│ │ └── integrated
│ │ └── ptr
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── culiu
│ │ └── mhvp
│ │ └── integrated
│ │ └── ptr
│ │ ├── PullToRefreshInnerListView.java
│ │ ├── PullToRefreshInnerScrollView.java
│ │ └── pulltorefresh
│ │ ├── ILoadingLayout.java
│ │ ├── IPullToRefresh.java
│ │ ├── LoadingLayoutProxy.java
│ │ ├── OverscrollHelper.java
│ │ ├── PullToRefreshAdapterViewBase.java
│ │ ├── PullToRefreshBase.java
│ │ └── internal
│ │ ├── EmptyViewMethodAccessor.java
│ │ ├── FlipLoadingLayout.java
│ │ ├── IndicatorLayout.java
│ │ ├── LoadingLayout.java
│ │ ├── RotateLoadingLayout.java
│ │ ├── Utils.java
│ │ └── ViewCompat.java
│ └── res
│ ├── anim
│ ├── slide_in_from_bottom.xml
│ ├── slide_in_from_top.xml
│ ├── slide_out_to_bottom.xml
│ └── slide_out_to_top.xml
│ ├── drawable-xhdpi
│ ├── default_ptr_flip.png
│ └── default_ptr_rotate.png
│ ├── drawable
│ ├── indicator_bg_bottom.xml
│ └── indicator_bg_top.xml
│ ├── layout
│ └── default_pull_to_refresh_header_vertical.xml
│ └── values
│ ├── dimens.xml
│ ├── ids.xml
│ ├── ptr_arrays.xml
│ ├── ptr_attr.xml
│ └── strings.xml
├── pics
├── 1.gif
├── 2.gif
├── 3.gif
├── 4.gif
├── 5.gif
├── 6.gif
├── 7.gif
└── 8.gif
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | #built application files
2 | #*.apk
3 | *.ap_
4 |
5 | # files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # generated files
12 | bin/
13 | gen/
14 |
15 | # Local configuration file (sdk path, etc)
16 | #local.properties
17 |
18 | # Windows thumbnail db
19 | Thumbs.db
20 |
21 | # OSX files
22 | .DS_Store
23 |
24 | # Eclipse project files
25 | .classpath
26 | .project
27 |
28 | # Android Studio
29 | *.iml
30 | .idea
31 | #.idea/workspace.xml - remove # and delete .idea if it better suit your needs.
32 | .gradle
33 | build/
34 | /captures
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Deprecated
2 | This project is archived.
3 |
4 | # MagicHeaderViewPager
5 | HeaderViewPager with a header can be fixed and many scrollable Fragments (listFragments, gridFragments and ScrollFragments) inside.
6 |
7 | # Introduction
8 | ### 0. Example
9 | **0.1、Simply immobilizing tabs and keeping locaiton**
10 |
11 | 
12 |
13 |
14 |
15 | **0.2、Support large Header taller than screen**
16 |
17 | 
18 |
19 |
20 |
21 | **0.3、Support Mixed ListView items and their heights need not be the same**
22 |
23 | 
24 |
25 |
26 |
27 | **0.4、Combined with pull to refresh**
28 |
29 | 
30 |
31 |
32 |
33 | **0.5、Magic header can be drag down as you like. The header and inner ListView(ScrollView) can respond touch respctively**
34 |
35 | 
36 |
37 |
38 |
39 | **0.6、Inner Scroller(ListView、GridView、ScrollView) can be scrolled even if content is null, and the empty content can be customized to improve user experience**
40 |
41 | 
42 |
43 |
44 |
45 | **0.7、Dispatch touch event as expected**
46 |
47 | 
48 |
49 |
50 |
51 | **0.8、Example of height auto completion: empty content colored green, and auto completion colored blue**
52 |
53 | 
54 |
55 |
56 |
57 | ### 1. Dependency
58 |
59 | Add the following lines to your build.gradle for pure MagicHeaderViewPager.
60 | ```Java
61 | dependencies {
62 | compile 'com.culiu.android:mhvp-core:2.1.2@aar'
63 | }
64 | ```
65 |
66 | For using integrated Pull-To-Refresh:
67 | ```Java
68 | dependencies {
69 | compile 'com.culiu.android:mhvp-core:2.1.2@aar'
70 | compile 'com.culiu.android:mhvp-integrated-ptr:2.1.2@aar'
71 | }
72 | ```
73 |
74 | For more details, see [Guide](https://github.com/XavierSAndroid/MagicHeaderViewPager/tree/master/doc) or [Demo](https://github.com/XavierSAndroid/MagicHeaderViewPager/tree/master/demo).
75 |
76 | # Developed By
77 |
78 | * Xavier S -
79 | * https://github.com/XavierSAndroid https://github.com/CuliuDev
80 |
81 | # License
82 |
83 | Copyright (c) 2015 [Xavier-S](mailto:X.S.Xavier.S@gmail.com)
84 |
85 | Licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
86 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.0.0-alpha1'
9 |
10 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2'
11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3'
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | jcenter()
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/demo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/demo/MagicHeaderViewPager_demo.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/MagicHeaderViewPager_demo.jks
--------------------------------------------------------------------------------
/demo/apk/MagicHeaderViewPager_demo_1.0.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/apk/MagicHeaderViewPager_demo_1.0.apk
--------------------------------------------------------------------------------
/demo/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | android {
3 | compileSdkVersion 21
4 | buildToolsVersion '23.0.2'
5 |
6 | defaultConfig {
7 | applicationId "com.culiu.mhvp"
8 | minSdkVersion 7
9 | targetSdkVersion 21
10 | versionCode 57
11 | versionName "3.3"
12 | }
13 |
14 | signingConfigs {
15 | myConfig {
16 | storeFile file("MagicHeaderViewPager_demo.jks")
17 | storePassword "123456"
18 | keyAlias "com.culiu.mhvp"
19 | keyPassword "123456"
20 | }
21 | }
22 |
23 | buildTypes {
24 | release {
25 | signingConfig signingConfigs.myConfig
26 | minifyEnabled false
27 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
28 | }
29 | }
30 |
31 | lintOptions {
32 | abortOnError false
33 | }
34 |
35 | }
36 | task clearApk(type: Delete) {
37 | delete '../apk/' + POM_ARTIFACT_ID + '_' + VERSION_NAME + '.apk'
38 | }
39 | task makeApk(type: Copy) {
40 | from('build/outputs/apk/')
41 | into('apk/')
42 | include("demo-release.apk")
43 | rename("demo-release.apk", POM_ARTIFACT_ID + '_' + VERSION_NAME + '.apk')
44 | }
45 | makeApk.dependsOn(clearApk, build)
46 |
47 | // local dependencies
48 | dependencies {
49 | compile project(':mhvp-integrated-ptr')
50 | }
51 |
52 | // remote dependencies
53 | //dependencies {
54 | // compile 'com.android.support:support-v4:21.0.3'
55 | // compile 'com.culiu.android:mhvp-core:2.1.2@aar'
56 | // compile 'com.culiu.android:mhvp-integrated-ptr:2.1.2@aar'
57 | //}
--------------------------------------------------------------------------------
/demo/gradle.properties:
--------------------------------------------------------------------------------
1 | POM_ARTIFACT_ID=MagicHeaderViewPager
2 | VERSION_NAME=demo_1.0
--------------------------------------------------------------------------------
/demo/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Applications/eclipse-ADT/android-sdk-macosxs/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/demo/src/androidTest/java/com/culiu/mhvp/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/demo/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/APP.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | /**
7 | * @author Xavier-S
8 | * @date 2015.11.27 20:09
9 | */
10 | public class APP extends Application {
11 |
12 | private static APP mApplication;
13 |
14 | private static Context mApplicationContext;
15 |
16 | @Override
17 | public void onCreate() {
18 | super.onCreate();
19 | synchronized(APP.this) {
20 | mApplicationContext = getApplicationContext();
21 | mApplication = this;
22 | }
23 | }
24 |
25 | @Override
26 | public Context getApplicationContext() {
27 | return mApplicationContext;
28 | }
29 |
30 | public static APP getInstance() {
31 | return mApplication;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/AbsDemoFragment.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 | import android.app.Activity;
4 | import android.os.Handler;
5 | import android.support.v4.app.Fragment;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ImageView;
9 | import android.widget.LinearLayout;
10 |
11 | import com.culiu.mhvp.R;
12 | import com.culiu.mhvp.core.InnerScrollerContainer;
13 | import com.culiu.mhvp.core.OuterScroller;
14 | import com.culiu.mhvp.integrated.ptr.pulltorefresh.PullToRefreshBase;
15 |
16 | /**
17 | * @author Xavier-S
18 | *
19 | * Extracted codes for demo. In you practice, there's no need to
20 | * create an AbsFragment to extend it. Just let your fragment
21 | * implement InnerScrollerContainer. It's ok and good enough.
22 | *
23 | * @date 2015.11.12 11:20
24 | */
25 | public abstract class AbsDemoFragment extends Fragment implements InnerScrollerContainer, PullToRefreshBase.OnRefreshListener2 {
26 |
27 | /************* InnerScrollerContainer interface **************/
28 |
29 | protected OuterScroller mOuterScroller;
30 | protected int mIndex;
31 | @Override
32 | public void setOuterScroller(OuterScroller outerScroller, int myPosition) {
33 | if(outerScroller == mOuterScroller && myPosition == mIndex) {
34 | return;
35 | }
36 | mOuterScroller = outerScroller;
37 | mIndex = myPosition;
38 |
39 | if(getInnerScroller() != null) {
40 | getInnerScroller().register2Outer(mOuterScroller, mIndex);
41 | }
42 | }
43 | /************* InnerScrollerContainer interface End **************/
44 |
45 |
46 |
47 | /****************************** Test code ******************************/
48 | /**
49 | * Emulate http asynchronous loading
50 | */
51 | protected void requestData() {
52 | new Handler().postDelayed(new Runnable() {
53 | @Override
54 | public void run() {
55 | onResponse();
56 | }
57 | }, 1500);
58 | }
59 |
60 | public abstract void onResponse();
61 |
62 | @Override
63 | public void onAttach(Activity activity) {
64 | super.onAttach(activity);
65 | }
66 |
67 | /**
68 | * After pull to refresh, add a random picture
69 | */
70 | public View addRandomPic() {
71 |
72 | ImageView iv = new ImageView(getActivity());
73 | iv.setScaleType(ImageView.ScaleType.FIT_XY);
74 | iv.setImageResource(RandomPic.getInstance().getPicResId());
75 | iv.setAdjustViewBounds(true);
76 |
77 | LinearLayout.LayoutParams lpIv = new LinearLayout.LayoutParams(
78 | LinearLayout.LayoutParams.MATCH_PARENT,
79 | ViewGroup.LayoutParams.WRAP_CONTENT
80 | );
81 |
82 | LinearLayout ll = new LinearLayout(getActivity());
83 | ll.addView(iv, lpIv);
84 | getInnerScroller().addHeaderView(ll);
85 |
86 | return ll;
87 | }
88 |
89 | View tempChild = null;
90 |
91 | @Override
92 | public void onPullDownToRefresh(PullToRefreshBase refreshView) {
93 | // Update the whole state, and forbidden touch
94 | getInnerScroller().onRefresh(true);
95 |
96 | new Handler().postDelayed(new Runnable() {
97 | @Override
98 | public void run() {
99 | // Return to normal state
100 | getInnerScroller().onRefresh(false);
101 | // Test code
102 | switch (WelcomeActivity.demoType) {
103 | case Pull_to_add_Magic_Header_Mixed:
104 | case Pull_to_add_Magic_Header_Mixed_Complicated_header:
105 | if (getActivity() instanceof DemoActivity) {
106 | ((DemoActivity) getActivity()).addRandomPic();
107 | }
108 | break;
109 | case Pull_to_add_Inner_Header_Mixed:
110 | addRandomPic();
111 | break;
112 | default:
113 | // nothing
114 | break;
115 | }
116 | if (getInnerScroller().getReceiveView() instanceof PullToRefreshBase) {
117 | ((PullToRefreshBase)getInnerScroller().getReceiveView()).onRefreshComplete();
118 | }
119 | }
120 | }, 2000);
121 | }
122 |
123 | @Override
124 | public void onPullUpToRefresh(PullToRefreshBase refreshView) {
125 | }
126 | /****************************** Test code End ******************************/
127 | }
128 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/DemoActivity.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 | import android.graphics.Color;
4 | import android.graphics.drawable.Drawable;
5 | import android.os.Bundle;
6 | import android.support.v4.app.FragmentActivity;
7 | import android.support.v4.view.ViewPager;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.Button;
12 | import android.widget.HorizontalScrollView;
13 | import android.widget.ImageView;
14 | import android.widget.LinearLayout;
15 | import android.widget.Toast;
16 |
17 | import com.culiu.mhvp.R;
18 | import com.culiu.mhvp.core.MagicHeaderUtils;
19 | import com.culiu.mhvp.core.MagicHeaderViewPager;
20 | import com.culiu.mhvp.core.tabs.com.astuetz.PagerSlidingTabStrip;
21 |
22 | public class DemoActivity extends FragmentActivity {
23 |
24 | public static final String TAG = "sz[mhvp-demo]";
25 |
26 | private MagicHeaderViewPager mMagicHeaderViewPager;
27 | private DemoPagerAdapter mPagerAdapter;
28 |
29 | @Override
30 | protected void onCreate(Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 | setContentView(R.layout.activity_mhvp_demo);
33 |
34 |
35 | /* TODO: Initialize MagicHeaderViewPager. Override initTabsArea() to initialize tabs or stable area. */
36 | mMagicHeaderViewPager = new MagicHeaderViewPager(this) {
37 | @Override
38 | protected void initTabsArea(LinearLayout container) {
39 | //You can customize your tabStrip or stable area here
40 | ViewGroup tabsArea = (ViewGroup) LayoutInflater.from(DemoActivity.this).inflate(R.layout.layout_tabs1, null);
41 |
42 | // TODO: Set height of stable area manually, then it can be calculated.
43 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
44 | MagicHeaderUtils.dp2px(DemoActivity.this, 48));
45 | container.addView(tabsArea, lp);
46 |
47 | // some style
48 | PagerSlidingTabStrip pagerSlidingTabStrip = (PagerSlidingTabStrip) tabsArea.findViewById(R.id.tabs);
49 | pagerSlidingTabStrip.setTextColor(Color.BLACK);
50 | pagerSlidingTabStrip.setBackgroundColor(Color.WHITE);
51 |
52 | // TODO: These two methods must be called to let magicHeaderViewPager know who is stable area and tabs.
53 | setTabsArea(tabsArea);
54 | setPagerSlidingTabStrip(pagerSlidingTabStrip);
55 | }
56 | };
57 | // Note: Cuz tabs or stable area of each ViewPager may not
58 | // the same. So it's abstract for developers to override.
59 |
60 | //TODO: Just add MagicHeaderViewPager into your Layout. MATCH_PARENT-MATCH_PARENT is recommended.
61 | LinearLayout mhvpParent = (LinearLayout) findViewById(R.id.mhvp_parent);
62 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
63 | LinearLayout.LayoutParams.MATCH_PARENT,
64 | LinearLayout.LayoutParams.MATCH_PARENT
65 | );
66 | mhvpParent.addView(mMagicHeaderViewPager, lp);
67 |
68 | // TODO: Use an OuterPagerAdapter as FragmentPagerAdapter
69 | mPagerAdapter = new DemoPagerAdapter(getSupportFragmentManager());
70 |
71 | // TODO: Use this method instead of those of PagerSlidingTabStrip or ViewPager.
72 | mMagicHeaderViewPager.setPagerAdapter(mPagerAdapter);
73 |
74 | // call this if needed
75 | mMagicHeaderViewPager.setTabOnPageChangeListener(new ViewPager.OnPageChangeListener() {
76 | @Override
77 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
78 | }
79 |
80 | @Override
81 | public void onPageSelected(int position) {
82 | }
83 |
84 | @Override
85 | public void onPageScrollStateChanged(int state) {
86 | }
87 | });
88 |
89 | // Then you can do anything like before:)
90 |
91 | // add your custom Header content
92 | initCustomHeader();
93 |
94 | }
95 |
96 |
97 | /************************************************************
98 | **** Test code ****
99 | ************************************************************/
100 |
101 | private void initCustomHeader() {
102 | if (WelcomeActivity.demoType != DemoConfig.DemoType.Pull_to_add_Magic_Header_Mixed_Complicated_header) {
103 | // Simply add a picture
104 | addRandomPic();
105 | } else {
106 | // Example: add a custom Layout
107 |
108 | View customLayout = LayoutInflater.from(this).inflate(R.layout.header_custom_layout, null);
109 | Button btn = ((Button) customLayout.findViewById(R.id.button));
110 | btn.setOnClickListener(new View.OnClickListener() {
111 | @Override
112 | public void onClick(View v) {
113 | Toast.makeText(DemoActivity.this, "btn Clicked", Toast.LENGTH_SHORT).show();
114 | }
115 | });
116 | mMagicHeaderViewPager.addHeaderView(customLayout);
117 |
118 | HorizontalScrollView sv = new HorizontalScrollView(this);
119 | LinearLayout ll = new LinearLayout(this);
120 | ll.setOrientation(LinearLayout.HORIZONTAL);
121 | for (int i = 5; i > 0; i--) {
122 | ImageView iv = new ImageView(this);
123 | iv.setScaleType(ImageView.ScaleType.FIT_XY);
124 | iv.setImageResource(RandomPic.getInstance().getPicResId());
125 | ll.addView(iv, new LinearLayout.LayoutParams(MagicHeaderUtils.getScreenWidth(this), (int) (MagicHeaderUtils.getScreenWidth(this)*.66f)));
126 | }
127 | sv.addView(ll, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
128 | mMagicHeaderViewPager.addHeaderView(sv);
129 | }
130 | }
131 |
132 | /**
133 | * Add a random picture
134 | */
135 | public void addRandomPic() {
136 | ImageView iv = new ImageView(this);
137 | iv.setScaleType(ImageView.ScaleType.FIT_XY);
138 | Drawable drawable = getResources().getDrawable(RandomPic.getInstance().getPicResId());
139 | iv.setImageDrawable(drawable);
140 | int height = MagicHeaderUtils.getHeightWhenFullWidth(this, drawable);
141 | mMagicHeaderViewPager.addHeaderView(iv, height);
142 | }
143 |
144 | /************************************************************
145 | **** Test code End ****
146 | ************************************************************/
147 | }
148 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/DemoConfig.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 | import android.graphics.Color;
4 |
5 | import com.culiu.mhvp.R;
6 |
7 | /**
8 | * @author Xavier-S
9 | * @date 2015.11.19 11:55
10 | */
11 | public interface DemoConfig {
12 |
13 | /**
14 | * Demo子页面对应的类型
15 | */
16 | enum DemoType {
17 | Only_ListView,
18 | Only_Scrollview, Only_GridView, Not_Pullable_Mixed,
19 | Pull_to_add_Inner_Header_Mixed, Pull_to_add_Magic_Header_Mixed,
20 | Pull_to_add_Magic_Header_Mixed_Complicated_header
21 | }
22 |
23 |
24 | /**
25 | * 用配色帮助理解
26 | */
27 | boolean ENABLE_COLOR = true;
28 |
29 | /**
30 | * 空白内容的颜色
31 | */
32 | int COLOR_EMPTY_CONTENT = Color.TRANSPARENT;
33 |
34 | /**
35 | * 自动补全(内容)的颜色
36 | */
37 | int COLOR_CONTENT_AUTO_COMPLETION = Color.TRANSPARENT;
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/DemoGridFragment.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 | import android.view.LayoutInflater;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 |
9 | import com.culiu.mhvp.R;
10 | import com.culiu.mhvp.core.MagicHeaderUtils;
11 | import com.culiu.mhvp.core.tabs.GridViewWithHeaderBaseAdapter;
12 |
13 | import java.util.ArrayList;
14 |
15 | /**
16 | * Created by Xavier-S on 15/7/23.
17 | */
18 | public class DemoGridFragment extends DemoListFragment {
19 |
20 | /**
21 | * Using LinearLayout in ListView items to realize
22 | * gridView result.
23 | */
24 | protected void initAdapter() {
25 | if (mListItems == null) {
26 | mListItems = new ArrayList- ();
27 | }
28 | mAdapter = new GridViewWithHeaderBaseAdapter(getActivity()) {
29 | @Override
30 | protected void setPaddingAndMargin(View leftView, View rightView, int culumn) {
31 | super.setPaddingAndMargin(leftView, rightView, culumn);
32 | int _5dp = MagicHeaderUtils.dp2px(getActivity(), 5f);
33 | leftView.setPadding(_5dp, 0, _5dp / 2, 0);
34 | rightView.setPadding(_5dp / 2, 0, _5dp, 0);
35 | }
36 |
37 | @Override
38 | public int getItemCount() {
39 | return mListItems.size();
40 | }
41 |
42 | @Override
43 | protected View getItemView(int position, View convertView, ViewGroup parent) {
44 | if (convertView == null) {
45 | convertView = LayoutInflater.from(getActivity()).inflate(R.layout.item_grid_fragment, null);
46 | }
47 | ImageView iv = (ImageView) convertView.findViewById(R.id.iv);
48 | TextView tv = (TextView) convertView.findViewById(R.id.tv);
49 | iv.setImageResource(getItem(position).getDrawableResId());
50 | tv.setText(getItem(position).getTitle());
51 | return convertView;
52 | }
53 |
54 | @Override
55 | public Item getItem(int position) {
56 | return mListItems.get(position);
57 | }
58 |
59 | @Override
60 | public long getItemId(int position) {
61 | return 0;
62 | }
63 | };
64 | ((GridViewWithHeaderBaseAdapter) mAdapter).setNumColumns(2);
65 | mListView.setAdapter(mAdapter);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/DemoListFragment.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 | import android.graphics.Color;
4 | import android.graphics.drawable.ColorDrawable;
5 | import android.os.Bundle;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.BaseAdapter;
10 | import android.widget.ImageView;
11 | import android.widget.LinearLayout;
12 | import android.widget.TextView;
13 |
14 | import com.culiu.mhvp.R;
15 | import com.culiu.mhvp.core.InnerListView;
16 | import com.culiu.mhvp.core.InnerScroller;
17 | import com.culiu.mhvp.core.MagicHeaderUtils;
18 |
19 | import java.util.ArrayList;
20 |
21 | /**
22 | * Created by Xavier-S on 15/7/23.
23 | */
24 | public class DemoListFragment extends AbsDemoFragment {
25 |
26 | /************* InnerScrollerContainer interface **************/
27 | protected InnerListView mListView;
28 |
29 | /**
30 | * TODO: make sure through this method, can get your InnerScroller(InnerListView) in your fragment.
31 | * @return
32 | */
33 | @Override
34 | public InnerScroller getInnerScroller() {
35 | return mListView;
36 | }
37 |
38 | @Override
39 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
40 | if (mListView != null && viewThis != null) {
41 | if (viewThis.getParent() != null) {
42 | ((ViewGroup) viewThis.getParent()).removeView(viewThis);
43 | }
44 | return viewThis;
45 | }
46 | viewThis = inflater.inflate(R.layout.fragment_list, null);
47 |
48 | // TODO: Be sure have put PullToRefreshInnerListView or InnerListView in your layout and its height match parent or align parent's top.
49 | mListView = (InnerListView) viewThis.findViewById(R.id.listView);
50 |
51 | mListView.setSelector(new ColorDrawable(Color.TRANSPARENT));
52 | mListView.setDividerHeight(0);
53 |
54 | // TODO: Every time listView initialized, don't forget to call registerToOuter.
55 | mListView.register2Outer(mOuterScroller, mIndex);
56 |
57 | // Demo: Use color to mark special areas.
58 | if(DemoConfig.ENABLE_COLOR) {
59 | // Optional: Customize empty content
60 | View colorView = new View(getActivity());
61 | colorView.setBackgroundColor(DemoConfig.COLOR_EMPTY_CONTENT);
62 | mListView.setCustomEmptyView(colorView);
63 | mListView.setCustomEmptyViewHeight(ViewGroup.LayoutParams.MATCH_PARENT, 0);
64 |
65 | // Demo: color its auto completion area
66 | mListView.setContentAutoCompletionColor(DemoConfig.COLOR_CONTENT_AUTO_COMPLETION);
67 | }
68 |
69 | // Two ways to load data: 1. initAdapter(); then notifyDataSetChanged(); 2. requestData(); then initAdapter();
70 | // demonstrate the 2nd way
71 | requestData();
72 |
73 | return viewThis;
74 | }
75 |
76 | /************* InnerScrollerContainer interface End **************/
77 |
78 |
79 | /*********************** Test data ***********************/
80 |
81 | protected ArrayList
- mListItems;
82 |
83 | public class Item {
84 | private String title;
85 | private int drawableResId;
86 |
87 | public Item(String title, int drawableResId) {
88 | this.title = title;
89 | this.drawableResId = drawableResId;
90 | }
91 |
92 | public String getTitle() {
93 | return title;
94 | }
95 |
96 | public void setTitle(String title) {
97 | this.title = title;
98 | }
99 |
100 | public int getDrawableResId() {
101 | return drawableResId;
102 | }
103 |
104 | public void setDrawableResId(int drawableResId) {
105 | this.drawableResId = drawableResId;
106 | }
107 | }
108 |
109 |
110 | protected BaseAdapter mAdapter;
111 |
112 | @Override
113 | public void onCreate(Bundle savedInstanceState) {
114 | super.onCreate(savedInstanceState);
115 | }
116 |
117 | public void onResponse() {
118 | if(getActivity() == null || getActivity().isFinishing()) {
119 | return;
120 | }
121 |
122 | if (mListItems == null) {
123 | mListItems = new ArrayList
- ();
124 | }
125 | for (int i = 1; i <= 15; i++) {
126 | mListItems.add(new Item("list: " + (mIndex + 1) + "'s item " + i, RandomPic.getInstance().getPicResId()));
127 | }
128 |
129 | initAdapter();
130 | }
131 |
132 |
133 | protected void initAdapter() {
134 | if (mListItems == null) {
135 | mListItems = new ArrayList
- ();
136 | }
137 |
138 | mAdapter = new BaseAdapter(
139 |
140 | ) {
141 | @Override
142 | public int getCount() {
143 | return mListItems.size();
144 | }
145 |
146 | @Override
147 | public Item getItem(int position) {
148 | return mListItems.get(position);
149 | }
150 |
151 | @Override
152 | public long getItemId(int position) {
153 | return 0;
154 | }
155 |
156 | int picHeight = (int) (MagicHeaderUtils.getScreenWidth(getActivity()) * 0.68f);
157 |
158 | @Override
159 | public View getView(int position, View convertView, ViewGroup parent) {
160 | if (convertView == null) {
161 | convertView = LayoutInflater.from(getActivity()).inflate(R.layout.item_list_fragment, null);
162 | }
163 | ImageView iv = (ImageView) convertView.findViewById(R.id.iv);
164 | TextView tv = (TextView) convertView.findViewById(R.id.tv);
165 | iv.setImageResource(mListItems.get(position).getDrawableResId());
166 | tv.setText(getItem(position).getTitle());
167 |
168 | LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) iv.getLayoutParams();
169 | if (lp.height != picHeight) {
170 | lp.height = picHeight;
171 | iv.setLayoutParams(lp);
172 | }
173 |
174 | return convertView;
175 | }
176 | };
177 | mListView.setAdapter(mAdapter);
178 | }
179 |
180 | protected View viewThis;
181 | }
182 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/DemoPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentPagerAdapter;
6 | import android.view.ViewGroup;
7 |
8 | import com.culiu.mhvp.core.InnerScrollerContainer;
9 | import com.culiu.mhvp.core.OuterPagerAdapter;
10 | import com.culiu.mhvp.core.OuterScroller;
11 |
12 | /**
13 | * @author Xavier-S
14 | * @date 2015.10.08 20:33
15 | */
16 | public class DemoPagerAdapter extends FragmentPagerAdapter implements OuterPagerAdapter{
17 |
18 |
19 | /**** OuterPagerAdapter methods ****/
20 | private OuterScroller mOuterScroller;
21 |
22 | @Override
23 | public void setOuterScroller(OuterScroller outerScroller) {
24 | mOuterScroller = outerScroller;
25 | }
26 |
27 | @Override
28 | public Object instantiateItem(ViewGroup container, int position) {
29 | // TODO: Make sure to put codes below in your PagerAdapter's instantiateItem()
30 | // cuz Fragment has some weird life cycle.
31 | InnerScrollerContainer fragment =
32 | (InnerScrollerContainer) super.instantiateItem(container, position);
33 |
34 | if (null != mOuterScroller) {
35 | fragment.setOuterScroller(mOuterScroller, position);
36 | }
37 | return fragment;
38 | }
39 | /**** OuterPagerAdapter methods End ****/
40 |
41 |
42 | /************************ Test data *********************/
43 | public DemoPagerAdapter(FragmentManager fm) {
44 | super(fm);
45 | }
46 |
47 | protected CharSequence[] mTitles = {"page 1", "page 2", "page 3", "page 4"/*, "page 5", "page 6"*/};
48 |
49 | @Override
50 | public CharSequence getPageTitle(int position) {
51 | return mTitles[position];
52 | }
53 |
54 | @Override
55 | public int getCount() {
56 | return mTitles.length;
57 | }
58 |
59 | @Override
60 | public final Fragment getItem(int position) {
61 | Fragment fragment;
62 |
63 | switch (WelcomeActivity.demoType) {
64 | case Only_ListView:
65 | fragment = new DemoListFragment();
66 | break;
67 | case Only_GridView:
68 | fragment = new DemoGridFragment();
69 | break;
70 | case Only_Scrollview:
71 | fragment = new DemoScrollFragment();
72 | break;
73 | case Not_Pullable_Mixed:
74 | fragment = getMixedFragment(position);
75 | break;
76 | case Pull_to_add_Inner_Header_Mixed:
77 | case Pull_to_add_Magic_Header_Mixed:
78 | case Pull_to_add_Magic_Header_Mixed_Complicated_header:
79 | fragment = getMixedPullableFragment(position);
80 | break;
81 | default:
82 | fragment = new DemoGridFragment();
83 | break;
84 | }
85 | return fragment;
86 | }
87 |
88 | private Fragment getMixedFragment(int position) {
89 | switch (position % 3) {
90 | case 0:
91 | return new DemoListFragment();
92 | case 1:
93 | return new DemoGridFragment();
94 | case 2:
95 | return new DemoScrollFragment();
96 | default:
97 | return new DemoGridFragment();
98 | }
99 | }
100 |
101 | private Fragment getMixedPullableFragment(int position) {
102 | switch (position % 3) {
103 | case 0:
104 | return new DemoPullToRefreshListFragment();
105 | case 1:
106 | return new DemoPullToRefreshScrollFragment();
107 | case 2:
108 | return new DemoPullToRefreshGridFragment();
109 | default:
110 | return new DemoPullToRefreshGridFragment();
111 | }
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/DemoPullToRefreshGridFragment.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 | import android.view.LayoutInflater;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 |
9 | import com.culiu.mhvp.R;
10 | import com.culiu.mhvp.core.MagicHeaderUtils;
11 | import com.culiu.mhvp.core.tabs.GridViewWithHeaderBaseAdapter;
12 |
13 | import java.util.ArrayList;
14 |
15 | /**
16 | * Created by Xavier-S on 15/7/23.
17 | */
18 | public class DemoPullToRefreshGridFragment extends DemoPullToRefreshListFragment {
19 |
20 | protected void initAdapter() {
21 | if (mListItems == null) {
22 | mListItems = new ArrayList
- ();
23 | }
24 |
25 | /**
26 | * Using LinearLayout in ListView items to realize
27 | * gridView result.
28 | */
29 | mAdapter = new GridViewWithHeaderBaseAdapter(getActivity()) {
30 |
31 | @Override
32 | protected void setPaddingAndMargin(View leftView, View rightView, int culumn) {
33 | super.setPaddingAndMargin(leftView, rightView, culumn);
34 | int _5dp = MagicHeaderUtils.dp2px(getActivity(), 5f);
35 | leftView.setPadding(_5dp, 0, _5dp / 2, 0);
36 | rightView.setPadding(_5dp / 2, 0, _5dp, 0);
37 | }
38 |
39 | @Override
40 | public int getItemCount() {
41 | return mListItems.size();
42 | }
43 |
44 | @Override
45 | protected View getItemView(int position, View convertView, ViewGroup parent) {
46 | if (convertView == null) {
47 | convertView = LayoutInflater.from(getActivity()).inflate(R.layout.item_grid_fragment, null);
48 | }
49 | ImageView iv = (ImageView) convertView.findViewById(R.id.iv);
50 | TextView tv = (TextView) convertView.findViewById(R.id.tv);
51 | iv.setImageResource(mListItems.get(position).getDrawableResId());
52 | tv.setText(getItem(position).getTitle());
53 | return convertView;
54 | }
55 |
56 | @Override
57 | public Item getItem(int position) {
58 | return mListItems.get(position);
59 | }
60 |
61 | @Override
62 | public long getItemId(int position) {
63 | return 0;
64 | }
65 | };
66 | ((GridViewWithHeaderBaseAdapter) mAdapter).setNumColumns(2);
67 | mListView.setAdapter(mAdapter);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/DemoPullToRefreshListFragment.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 | import android.graphics.Color;
4 | import android.graphics.drawable.ColorDrawable;
5 | import android.os.Bundle;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.BaseAdapter;
10 | import android.widget.ImageView;
11 | import android.widget.LinearLayout;
12 | import android.widget.TextView;
13 |
14 | import com.culiu.mhvp.R;
15 | import com.culiu.mhvp.core.MagicHeaderUtils;
16 | import com.culiu.mhvp.integrated.ptr.PullToRefreshInnerListView;
17 |
18 | import java.util.ArrayList;
19 |
20 | /**
21 | * Created by Xavier-S on 15/7/23.
22 | */
23 | public class DemoPullToRefreshListFragment extends DemoListFragment {
24 |
25 | public static final String TAG = "sz[InnerPullToRefresh]";
26 |
27 | protected PullToRefreshInnerListView mPullToRefreshListView;
28 |
29 | @Override
30 | public void onCreate(Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 | }
33 |
34 | protected View viewThis;
35 |
36 | @Override
37 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
38 | if (mListView != null && viewThis != null) {
39 | if (viewThis.getParent() != null) {
40 | ((ViewGroup) viewThis.getParent()).removeView(viewThis);
41 | }
42 | return viewThis;
43 | }
44 | viewThis = inflater.inflate(R.layout.fragment_pulltorefresh_list, null);
45 |
46 | // TODO: Be sure have put PullToRefreshInnerListView or InnerListView in your layout and its height match parent or align parent's top.
47 | mPullToRefreshListView = (PullToRefreshInnerListView) viewThis.findViewById(R.id.pull_refresh_inner_listview);
48 |
49 | // Set refreshing scale. You may change it or delete it if needed.
50 | mPullToRefreshListView.setScaleRefreshing(0.568f);
51 |
52 | if(mPullToRefreshListView!=null) {
53 | mPullToRefreshListView.setOnRefreshListener(this);
54 | }
55 |
56 | mListView = mPullToRefreshListView.getRefreshableView();
57 |
58 | mListView.setSelector(new ColorDrawable(Color.TRANSPARENT));
59 | mListView.setDividerHeight(0);
60 |
61 | // TODO: Every time listView initialized, don't forget to call registerToOuter.
62 | mListView.register2Outer(mOuterScroller, mIndex);
63 |
64 | // Demo: Use color to mark special areas.
65 | if(DemoConfig.ENABLE_COLOR) {
66 | // Optional: Customize empty content
67 | View colorView = new View(getActivity());
68 | colorView.setBackgroundColor(DemoConfig.COLOR_EMPTY_CONTENT);
69 | mListView.setCustomEmptyView(colorView);
70 | mListView.setCustomEmptyViewHeight(ViewGroup.LayoutParams.MATCH_PARENT, -1000);
71 |
72 | // Demo: color its auto completion area
73 | mListView.setContentAutoCompletionColor(DemoConfig.COLOR_CONTENT_AUTO_COMPLETION);
74 | }
75 |
76 | // Two ways to load data: 1. initAdapter(); then notifyDataSetChanged(); 2. requestData(); then initAdapter();
77 | // demonstrate the 2nd way
78 | requestData();
79 |
80 | return viewThis;
81 | }
82 |
83 | /************* InnerScrollerContainer interface End **************/
84 |
85 |
86 | /*********************** Test data ***********************/
87 |
88 | protected void initAdapter() {
89 | if (mListItems == null) {
90 | mListItems = new ArrayList
- ();
91 | }
92 |
93 | mAdapter = new BaseAdapter(
94 |
95 | ) {
96 | @Override
97 | public int getCount() {
98 | return mListItems.size();
99 | }
100 |
101 | @Override
102 | public Item getItem(int position) {
103 | return mListItems.get(position);
104 | }
105 |
106 | @Override
107 | public long getItemId(int position) {
108 | return 0;
109 | }
110 |
111 | int picHeight = (int) (MagicHeaderUtils.getScreenWidth(getActivity()) * 0.68f);
112 |
113 | @Override
114 | public View getView(int position, View convertView, ViewGroup parent) {
115 | if (convertView == null) {
116 | convertView = LayoutInflater.from(getActivity()).inflate(R.layout.item_list_fragment, null);
117 | }
118 | ImageView iv = (ImageView) convertView.findViewById(R.id.iv);
119 | TextView tv = (TextView) convertView.findViewById(R.id.tv);
120 | iv.setImageResource(getItem(position).getDrawableResId());
121 | tv.setText(getItem(position).getTitle());
122 |
123 | if (iv.getLayoutParams() != null) {
124 | LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) iv.getLayoutParams();
125 | if (lp.height != picHeight) {
126 | lp.height = picHeight;
127 | iv.setLayoutParams(lp);
128 | }
129 | }
130 | return convertView;
131 | }
132 | };
133 | mPullToRefreshListView.setAdapter(mAdapter);
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/DemoPullToRefreshScrollFragment.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import com.culiu.mhvp.R;
9 | import com.culiu.mhvp.integrated.ptr.PullToRefreshInnerScrollView;
10 |
11 | /**
12 | * @author Xavier-S
13 | * @date 2015.11.09 14:07
14 | */
15 | public class DemoPullToRefreshScrollFragment extends DemoScrollFragment {
16 |
17 |
18 | protected PullToRefreshInnerScrollView mPullToRefreshScrollView;
19 |
20 | public static final String TAG = "sz[InnerPullToRefresh]";
21 |
22 | @Override
23 | public void onCreate(Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 | }
26 |
27 | protected View viewThis;
28 |
29 |
30 | @Override
31 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
32 | if (mScrollView != null && viewThis != null) {
33 | if (viewThis.getParent() != null) {
34 | ((ViewGroup) viewThis.getParent()).removeView(viewThis);
35 | }
36 | return viewThis;
37 | }
38 | viewThis = inflater.inflate(R.layout.fragment_pulltorefresh_scrollview, null);
39 |
40 | // TODO: Be sure have put PullToRefreshInnerScrollView or InnerScrollView in your layout. ensure your ListView's height match parent or align parent's top.
41 | mPullToRefreshScrollView = (PullToRefreshInnerScrollView) viewThis.findViewById(R.id.pull_refresh_inner_scrollview);
42 |
43 | // Set refreshing scale. You may change it or delete it if you need.
44 | mPullToRefreshScrollView.setScaleRefreshing(0.568f);
45 |
46 | if(mPullToRefreshScrollView!=null) {
47 | mPullToRefreshScrollView.setOnRefreshListener(this);
48 | }
49 |
50 | mScrollView = mPullToRefreshScrollView.getRefreshableView();
51 |
52 | // TODO: Every time listView initialized, don't forget to call registerToOuter.
53 | mScrollView.register2Outer(mOuterScroller, mIndex);
54 |
55 | // Demo: Use color to mark special areas.
56 | if(DemoConfig.ENABLE_COLOR) {
57 | // Optional: Customize empty content
58 | View colorView = new View(getActivity());
59 | colorView.setBackgroundColor(DemoConfig.COLOR_EMPTY_CONTENT);
60 | mScrollView.setCustomEmptyView(colorView);
61 | mScrollView.setCustomEmptyViewHeight(ViewGroup.LayoutParams.MATCH_PARENT, -300);
62 |
63 | // Demo: color its auto completion area
64 | mScrollView.setContentAutoCompletionColor(DemoConfig.COLOR_CONTENT_AUTO_COMPLETION);
65 | }
66 |
67 | requestData();
68 |
69 | tempChild = addRandomPic();
70 |
71 | return viewThis;
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/DemoScrollFragment.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ImageView;
9 | import android.widget.LinearLayout;
10 | import android.widget.TextView;
11 |
12 | import com.culiu.mhvp.R;
13 | import com.culiu.mhvp.core.InnerScrollView;
14 | import com.culiu.mhvp.core.InnerScroller;
15 | import com.culiu.mhvp.core.MagicHeaderUtils;
16 |
17 | /**
18 | * @author Xavier-S
19 | * @date 2015.11.09 14:07
20 | */
21 | public class DemoScrollFragment extends AbsDemoFragment {
22 |
23 | /************* InnerScrollerContainer interface **************/
24 | protected InnerScrollView mScrollView;
25 |
26 | /**
27 | * TODO: make sure through this method, can get your InnerScroller(InnerListView) in your fragment.
28 | * @return
29 | */
30 | @Override
31 | public InnerScroller getInnerScroller() {
32 | return mScrollView;
33 | }
34 |
35 | protected View viewThis;
36 |
37 | @Override
38 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
39 | if (mScrollView != null && viewThis != null) {
40 | if (viewThis.getParent() != null) {
41 | ((ViewGroup) viewThis.getParent()).removeView(viewThis);
42 | }
43 | return viewThis;
44 | }
45 | viewThis = inflater.inflate(R.layout.fragment_scrollview, null);
46 |
47 | // TODO: Be sure have put PullToRefreshInnerScrollView or InnerScrollView in your layout and its height match parent or align parent's top.
48 | mScrollView = (InnerScrollView) viewThis.findViewById(R.id.inner_scrollview);
49 |
50 | // TODO: Every time scrollview initialized, don't forget to call registerToOuter.
51 | mScrollView.register2Outer(mOuterScroller, mIndex);
52 |
53 | // Demo: Use color to mark special areas.
54 | if(DemoConfig.ENABLE_COLOR) {
55 | // Optional: Customize empty content
56 | View colorView = new View(getActivity());
57 | colorView.setBackgroundColor(DemoConfig.COLOR_EMPTY_CONTENT);
58 | mScrollView.setCustomEmptyView(colorView);
59 | mScrollView.setCustomEmptyViewHeight(ViewGroup.LayoutParams.MATCH_PARENT, -300);
60 |
61 | // Demo: color its auto completion area
62 | mScrollView.setContentAutoCompletionColor(DemoConfig.COLOR_CONTENT_AUTO_COMPLETION);
63 | }
64 |
65 | requestData();
66 |
67 | return viewThis;
68 | }
69 |
70 | /************* InnerScrollerContainer interface End **************/
71 |
72 |
73 | /*********************** Test data ***********************/
74 |
75 | private TextView tv;
76 |
77 | @Override
78 | public void onCreate(Bundle savedInstanceState) {
79 | super.onCreate(savedInstanceState);
80 | }
81 |
82 | public void onResponse() {
83 |
84 | if(getActivity() == null || getActivity().isFinishing()) {
85 | return;
86 | }
87 |
88 | initContent();
89 | }
90 |
91 |
92 | LinearLayout mContentLinearLayout;
93 |
94 | private void initContent() {
95 | mScrollView.clearContent();
96 |
97 | if (getActivity() == null) {
98 | return;
99 | }
100 |
101 | mContentLinearLayout = new LinearLayout(getActivity());
102 | mContentLinearLayout.setOrientation(LinearLayout.VERTICAL);
103 |
104 | // picture
105 | ImageView iv = new ImageView(getActivity());
106 | iv.setImageResource(RandomPic.getInstance().getPicResId());
107 | iv.setAdjustViewBounds(true);
108 | int _5dp = MagicHeaderUtils.dp2px(getActivity(), 5f);
109 | iv.setPadding(_5dp, 0, _5dp, _5dp);
110 | mContentLinearLayout.addView(iv, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
111 |
112 | // Text data
113 | tv = new TextView(getActivity());
114 | tv.setText(getString(R.string.text_3_kingdoms_chapter_1));
115 | tv.setTextSize(20);
116 | tv.setTextColor(Color.parseColor("#2c3e50"));
117 | tv.setLineSpacing(0, 1.2f);
118 | tv.setPadding(_5dp, _5dp, _5dp, 0);
119 | mContentLinearLayout.addView(tv, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));
120 |
121 | mScrollView.setContentView(mContentLinearLayout);
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/RandomPic.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 | import com.culiu.mhvp.R;
4 |
5 | import java.util.ArrayList;
6 | import java.util.Collections;
7 | import java.util.List;
8 | import java.util.Random;
9 |
10 | /**
11 | * @author Xavier-S
12 | * @date 2015.11.27 20:02
13 | */
14 | public class RandomPic {
15 |
16 | private RandomPic() {
17 | random = new Random();
18 | mIntList = new ArrayList
();
19 | }
20 |
21 | public static RandomPic getInstance() {
22 | return Nested.instance;
23 | }
24 |
25 | private static class Nested {
26 | private static RandomPic instance = new RandomPic();
27 | }
28 |
29 | /**
30 | * 获得随机drawable图片资源id
31 | *
32 | * @return
33 | */
34 | public int getPicResId() {
35 | if (mIntList.size() == 0) {
36 | Collections.addAll(mIntList, picIds);
37 | }
38 | int index = random.nextInt(mIntList.size());
39 | int result = mIntList.get(index);
40 | mIntList.remove(index);
41 | return result;
42 | }
43 |
44 | private Random random;
45 | private List mIntList;
46 |
47 | Integer[] picIds = new Integer[]{R.drawable.bg_1, R.drawable.bg_2, R.drawable.bg_3, R.drawable.bg_4,
48 | R.drawable.bg_5, R.drawable.bg_6, R.drawable.bg_7, R.drawable.bg_8, R.drawable.bg_9,
49 | R.drawable.bg_10, R.drawable.bg_11, R.drawable.bg_12, R.drawable.bg_13};
50 | }
51 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/culiu/mhvp/demo/WelcomeActivity.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.demo;
2 |
3 |
4 | import android.app.Activity;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.view.View;
8 |
9 | import com.culiu.mhvp.R;
10 |
11 | /**
12 | * Created by Xavier-S on 15/7/26.
13 | */
14 | public class WelcomeActivity extends Activity {
15 |
16 | static DemoConfig.DemoType demoType;
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 |
22 | setContentView(R.layout.activity_welcome);
23 | }
24 |
25 | public void onClick(View view) {
26 | switch (view.getId()) {
27 | case R.id.btn_pure_listview:
28 | // Only ListView
29 | demoType = DemoConfig.DemoType.Only_ListView;
30 | break;
31 | case R.id.btn_pure_scrollview:
32 | // Only ScrollView
33 | demoType = DemoConfig.DemoType.Only_Scrollview;
34 | break;
35 | case R.id.btn_pure_gridview:
36 | // Only GridView
37 | demoType = DemoConfig.DemoType.Only_GridView;
38 | break;
39 | case R.id.btn_mix_innerscroller:
40 | // 混合,不可下拉刷新
41 | demoType = DemoConfig.DemoType.Not_Pullable_Mixed;
42 | break;
43 | case R.id.btn_pull_to_add_inner_header:
44 | // Mixed,pull to add an inner header
45 | demoType = DemoConfig.DemoType.Pull_to_add_Inner_Header_Mixed;
46 | break;
47 | case R.id.btn_pull_to_add_magic_header:
48 | // Mixed,pull to add an outer header (content in Magic Header)
49 | demoType = DemoConfig.DemoType.Pull_to_add_Magic_Header_Mixed;
50 | break;
51 | case R.id.btn_pull_to_add_magic_header_complicated_header:
52 | // Mixed,pull to add an outer header (content in Magic Header); header default to complicated layout
53 | demoType = DemoConfig.DemoType.Pull_to_add_Magic_Header_Mixed_Complicated_header;
54 | break;
55 | default:
56 | //nothing
57 | break;
58 | }
59 | startActivity(new Intent(this, DemoActivity.class));
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_1.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_10.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_11.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_12.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_13.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_2.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_3.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_4.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_5.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_6.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_7.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_8.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/bg_9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable-xxhdpi/bg_9.jpg
--------------------------------------------------------------------------------
/demo/src/main/res/drawable/bg_btn_welcome.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/demo/src/main/res/drawable/ptr_loading_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/drawable/ptr_loading_bg.png
--------------------------------------------------------------------------------
/demo/src/main/res/layout/activity_mhvp_demo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
12 |
13 |
20 |
21 |
30 |
31 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/activity_welcome.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
21 |
22 |
29 |
30 |
37 |
38 |
43 |
44 |
51 |
52 |
59 |
60 |
67 |
68 |
75 |
76 |
81 |
82 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/fragment_list.xml:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/fragment_pulltorefresh_list.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/fragment_pulltorefresh_scrollview.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/fragment_scrollview.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/header_custom_layout.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
16 |
17 |
26 |
27 |
37 |
38 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/item_grid_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
15 |
16 |
22 |
23 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/item_list_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
23 |
24 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/layout_tabs1.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
21 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/pull_to_refresh_header_vertical.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
16 |
20 |
21 |
27 |
28 |
36 |
37 |
38 |
44 |
45 |
54 |
55 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/demo/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ffffbb33
4 | #fff39c12
5 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MagicHeaderViewPager
3 | "三国演义 第一回 宴桃园豪杰三结义 斩黄巾英雄首立功:\n\n话说天下大势,分久必合,合久必分。周末七国分争,并入于秦。及秦灭之后,楚、汉分争,又并入于汉。汉朝自高祖斩白蛇而起义,一统天下,后来光武中兴,传至献帝,遂分为三国。推其致乱之由,殆始于桓、灵二帝。桓帝禁锢善类,崇信宦官。及桓帝崩,灵帝即位,大将军窦武、太傅陈蕃共相辅佐。时有宦官曹节等弄权,窦武、陈蕃谋诛之,机事不密,反为所害,中涓自此愈横。\n建宁二年四月望日,帝御温德殿。方升座,殿角狂风骤起。只见一条大青蛇,从梁上飞将下来,蟠于椅上。帝惊倒,左右急救入宫,百官俱奔避。须臾,蛇不见了。忽然大雷大雨,加以冰雹,落到半夜方止,坏却房屋无数。建宁四年二月,洛阳地震;又海水泛溢,沿海居民,尽被大浪卷入海中。光和元年,雌鸡化雄。六月朔,黑气十余丈,飞入温德殿中。秋七月,有虹现于玉堂;五原山岸,尽皆崩裂。种种不祥,非止一端。帝下诏问群臣以灾异之由,议郎蔡邕上疏,以为蜺堕鸡化,乃妇寺干政之所致,言颇切直。帝览奏叹息,因起更衣。曹节在后窃视,悉宣告左右;遂以他事陷邕于罪,放归田里。后张让、赵忠、封谞、段珪、曹节、侯览、蹇硕、程旷、夏恽、郭胜十人朋比为奸,号为“十常侍”。帝尊信张让,呼为“阿父”。朝政日非,以致天下人心思乱,盗贼蜂起。\n时巨鹿郡有兄弟三人,一名张角,一名张宝,一名张梁。那张角本是个不第秀才,因入山采药,遇一老人,碧眼童颜,手执藜杖,唤角至一洞中,以天书三卷授之,曰:“此名《太平要术》,汝得之,当代天宣化,普救世人;若萌异心,必获恶报。”角拜问姓名。老人曰:“吾乃南华老仙也。”言讫,化阵清风而去。角得此书,晓夜攻习,能呼风唤雨,号为“太平道人”。中平元年正月内,疫气流行,张角散施符水,为人治病,自称“大贤良师”。角有徒弟五百余人,云游四方,皆能书符念咒。次后徒众日多,角乃立三十六方,大方万余人,小方六七千,各立渠帅,称为将军;讹言:“苍天已死,黄天当立;岁在甲子,天下大吉。”令人各以白土书“甲子”二字于家中大门上。青、幽、徐、冀、荆、扬、兖、豫八州之人,家家侍奉大贤良师张角名字。角遣其党马元义,暗赍金帛,结交中涓封谞,以为内应。角与二弟商议曰:“至难得者,民心也。今民心已顺,若不乘势取天下,诚为可惜。”遂一面私造黄旗,约期举事;一面使弟子唐周,驰书报封谞。唐周乃径赴省中告变。帝召大将军何进调兵擒马元义,斩之;次收封谞等一干人下狱。张角闻知事露,星夜举兵,自称“天公将军”,张宝称“地公将军”,张梁称“人公将军”。申言于众曰:“今汉运将终,大圣人出。汝等皆宜顺天从正,以乐太平。”四方百姓,裹黄巾从张角反者四五十万。贼势浩大,官军望风而靡。何进奏帝火速降诏,令各处备御,讨贼立功。一面遣中郎将卢植、皇甫嵩、朱儁,各引精兵、分三路讨之。\n且说张角一军,前犯幽州界分。幽州太守刘焉,乃江夏竟陵人氏,汉鲁恭王之后也。当时闻得贼兵将至,召校尉邹靖计议。靖曰:“贼兵众,我兵寡,明公宜作速招军应敌。”刘焉然其说,随即出榜招募义兵。\n榜文行到涿县,引出涿县中一个英雄。那人不甚好读书;性宽和,寡言语,喜怒不形于色;素有大志,专好结交天下豪杰;生得身长七尺五寸,两耳垂肩,双手过膝,目能自顾其耳,面如冠玉,唇若涂脂;中山靖王刘胜之后,汉景帝阁下玄孙,姓刘名备,字玄德。昔刘胜之子刘贞,汉武时封涿鹿亭侯,后坐酎金失侯,因此遗这一枝在涿县。玄德祖刘雄,父刘弘。弘曾举孝廉,亦尝作吏,早丧。玄德幼孤,事母至孝;家贫,贩屦织席为业。家住本县楼桑村。其家之东南,有一大桑树,高五丈余,遥望之,童童如车盖。相者云:“此家必出贵人。”玄德幼时,与乡中小儿戏于树下,曰:“我为天子,当乘此车盖。”叔父刘元起奇其言,曰:“此儿非常人也!”因见玄德家贫,常资给之。年十五岁,母使游学,尝师事郑玄、卢植,与公孙瓒等为友。\n及刘焉发榜招军时,玄德年已二十八岁矣。当日见了榜文,慨然长叹。随后一人厉声言曰:“大丈夫不与国家出力,何故长叹?”玄德回视其人,身长八尺,豹头环眼,燕颔虎须,声若巨雷,势如奔马。玄德见他形貌异常,问其姓名。其人曰:“某姓张名飞,字翼德。世居涿郡,颇有庄田,卖酒屠猪,专好结交天下豪杰。恰才见公看榜而叹,故此相问。”玄德曰:“我本汉室宗亲,姓刘,名备。今闻黄巾倡乱,有志欲破贼安民,恨力不能,故长叹耳。”飞曰:“吾颇有资财,当招募乡勇,与公同举大事,如何。”玄德甚喜,遂与同入村店中饮酒。\n正饮间,见一大汉,推着一辆车子,到店门首歇了,入店坐下,便唤酒保:“快斟酒来吃,我待赶入城去投军。”玄德看其人:身长九尺,髯长二尺;面如重枣,唇若涂脂;丹凤眼,卧蚕眉,相貌堂堂,威风凛凛。玄德就邀他同坐,叩其姓名。其人曰:“吾姓关名羽,字长生,后改云长,河东解良人也。因本处势豪倚势凌人,被吾杀了,逃难江湖,五六年矣。今闻此处招军破贼,特来应募。”玄德遂以己志告之,云长大喜。同到张飞庄上,共议大事。飞曰:“吾庄后有一桃园,花开正盛;明日当于园中祭告天地,我三人结为兄弟,协力同心,然后可图大事。”玄德、云长齐声应曰:“如此甚好。”\n次日,于桃园中,备下乌牛白马祭礼等项,三人焚香再拜而说誓曰:“念刘备、关羽、张飞,虽然异姓,既结为兄弟,则同心协力,救困扶危;上报国家,下安黎庶。不求同年同月同日生,只愿同年同月同日死。皇天后土,实鉴此心,背义忘恩,天人共戮!”誓毕,拜玄德为兄,关羽次之,张飞为弟。祭罢天地,复宰牛设酒,聚乡中勇士,得三百余人,就桃园中痛饮一醉。来日收拾军器,但恨无马匹可乘。正思虑间,人报有两个客人,引一伙伴当,赶一群马,投庄上来。玄德曰:“此天佑我也!”三人出庄迎接。原来二客乃中山大商:一名张世平,一名苏双,每年往北贩马,近因寇发而回。玄德请二人到庄,置酒管待,诉说欲讨贼安民之意。二客大喜,愿将良马五十匹相送;又赠金银五百两,镔铁一千斤,以资器用。\n玄德谢别二客,便命良匠打造双股剑。云长造青龙偃月刀,又名“冷艳锯”,重八十二斤。张飞造丈八点钢矛。各置全身铠甲。共聚乡勇五百余人,来见邹靖。邹靖引见太守刘焉。三人参见毕,各通姓名。玄德说起宗派,刘焉大喜,遂认玄德为侄。不数日,人报黄巾贼将程远志统兵五万来犯涿郡。刘焉令邹靖引玄德等三人,统兵五百,前去破敌。玄德等欣然领军前进,直至大兴山下,与贼相见。贼众皆披发,以黄巾抹额。当下两军相对,玄德出马,左有云长,右有翼德,扬鞭大骂:“反国逆贼,何不早降!”程远志大怒,遣副将邓茂出战。张飞挺丈八蛇矛直出,手起处,刺中邓茂心窝,翻身落马。程远志见折了邓茂,拍马舞刀,直取张飞。云长舞动大刀,纵马飞迎。程远志见了,早吃一惊,措手不及,被云长刀起处,挥为两段。后人有诗赞二人曰:英雄露颖在今朝,一试矛兮一试刀。初出便将威力展,三分好把姓名标。\n众贼见程远志被斩,皆倒戈而走。玄德挥军追赶,投降者不计其数,大胜而回。刘焉亲自迎接,赏劳军士。次日,接得青州太守龚景牒文,言黄巾贼围城将陷,乞赐救援。刘焉与玄德商议。玄德曰:“备愿往救之。”刘焉令邹靖将兵五千,同玄德、关、张,投青州来。贼众见救军至,分兵混战。玄德兵寡不胜,退三十里下寨。\n玄德谓关、张曰:“贼众我寡;必出奇兵,方可取胜。”乃分关公引一千军伏山左,张飞引一千军伏山右,鸣金为号,齐出接应。次日,玄德与邹靖引军鼓噪而进。贼众迎战,玄德引军便退。贼众乘势追赶,方过山岭,玄德军中一齐鸣金,左右两军齐出,玄德摩军回身复杀。三路夹攻,贼众大溃。直赶至青州城下,太守龚景亦率民兵出城助战。贼势大败,剿戮极多,遂解青州之围。后人有诗赞玄德曰:运筹决算有神功,二虎还须逊一龙。初出便能垂伟绩,自应分鼎在孤穷。\n龚景犒军毕,邹靖欲回。玄德曰:“近闻中郎将卢植与贼首张角战于广宗,备昔曾师事卢植,欲往助之。”于是邹靖引军自回,玄德与关、张引本部五百人投广宗来。至卢植军中,入帐施礼,具道来意。卢植大喜,留在帐前听调。\n时张角贼众十五万,植兵五万,相拒于广宗,未见胜负。植谓玄德曰:“我今围贼在此,贼弟张梁、张宝在颍川,与皇甫嵩、朱儁对垒。汝可引本部人马,我更助汝一千官军,前去颍川打探消息,约期剿捕。”玄德领命,引军星夜投颍川来。\n时皇甫嵩、朱儁领军拒贼,贼战不利,退入长社,依草结营。嵩与儁计曰:“贼依草结营,当用火攻之。”遂令军士,每人束草一把,暗地埋伏。其夜大风忽起。二更以后,一齐纵火,嵩与儁各引兵攻击贼寨,火焰张天,贼众惊慌,马不及鞍,人不及甲,四散奔走。\n杀到天明,张梁、张宝引败残军士,夺路而走。忽见一彪军马,尽打红旗,当头来到,截住去路。为首闪出一将,身长七尺,细眼长髯,官拜骑都尉,沛国谯郡人也,姓曹名操字孟德。操父曹嵩,本姓夏侯氏,因为中常侍曹腾之养子,故冒姓曹。曹嵩生操,小字阿瞒,一名吉利。操幼时,好游猎,喜歌舞,有权谋,多机变。操有叔父,见操游荡无度,尝怒之,言于曹嵩。嵩责操。操忽心生一计,见叔父来,诈倒于地,作中风之状。叔父惊告嵩,嵩急视之。操故无恙。嵩曰:“叔言汝中风,今已愈乎?”操曰:“儿自来无此病;因失爱于叔父,故见罔耳。”嵩信其言。后叔父但言操过,嵩并不听。因此,操得恣意放荡。时人有桥玄者,谓操曰:“天下将乱,非命世之才不能济。能安之者,其在君乎?”南阳何顒见操,言:“汉室将亡,安天下者,必此人也。”汝南许劭,有知人之名。操往见之,问曰:“我何如人?”劭不答。又问,劭曰:“子治世之能臣,乱世之奸雄也。”操闻言大喜。年二十,举孝廉,为郎,除洛阳北部尉。初到任,即设五色棒十余条于县之四门,有犯禁者,不避豪贵,皆责之。中常侍蹇硕之叔,提刀夜行,操巡夜拿住,就棒责之。由是,内外莫敢犯者,威名颇震。后为顿丘令,因黄巾起,拜为骑都尉,引马步军五千,前来颍川助战。正值张梁、张宝败走,曹操拦住,大杀一阵,斩首万余级,夺得旗幡、金鼓、马匹极多。张梁、张宝死战得脱。操见过皇甫嵩、朱儁,随即引兵追袭张梁、张宝去了。\n却说玄德引关、张来颍川,听得喊杀之声,又望见火光烛天,急引兵来时,贼已败散。玄德见皇甫嵩、朱儁,具道卢植之意。嵩曰:“张梁、张宝势穷力乏,必投广宗去依张角。玄德可即星夜往助。”玄德领命,遂引兵复回。到得半路,只见一簇军马,护送一辆槛车,车中之囚,乃卢植也。玄德大惊,滚鞍下马,问其缘故。植曰:“我围张角,将次可破;因角用妖术,未能即胜。朝廷差黄门左丰前来体探,问我索取贿赂。我答曰:‘军粮尚缺,安有余钱奉承天使?’左丰挟恨,回奏朝廷,说我高垒不战,惰慢军心;因此朝廷震怒,遣中郎将董卓来代将我兵,取我回京问罪。”张飞听罢,大怒,要斩护送军人,以救卢植。玄德急止之曰:“朝廷自有公论,汝岂可造次?”军士簇拥卢植去了。关公曰:“卢中郎已被逮,别人领兵,我等去无所依,不如且回涿郡。”玄德从其言,遂引军北行。行无二日,忽闻山后喊声大震。玄德引关、张纵马上高冈望之,见汉军大败,后面漫山塞野,黄巾盖地而来,旗上大书“天公将军”。玄德曰:“此张角也!可速战!”三人飞马引军而出。张角正杀败董卓,乘势赴来,忽遇三人冲杀,角军大乱,败走五十余里。\n三人救了董卓回寨。卓问三人现居何职。玄德曰:“白身。”卓甚轻之,不为礼。玄德出,张飞大怒曰:“我等亲赴血战,救了这厮,他却如此无礼。若不杀之,难消我气!”便要提刀入帐来杀董卓。正是:人情势利古犹今,谁识英雄是白身?安得快人如翼德,尽诛世上负心人!毕竟董卓性命如何,且听下文分解。"
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/doc/README.md:
--------------------------------------------------------------------------------
1 | **Guide: How to implement simplest MagicHeaderViewPager?**
2 |
3 | 1.Add dependencies in your build.gradle
4 | ```Java
5 | dependencies {
6 | compile 'com.culiu.android:mhvp-core:2.1.2@aar'
7 | }
8 | ```
9 |
10 | 2.Build your DemoListFragment. Create a layout fragment_list.xml like:
11 | ```Xml
12 |
17 | ```
18 |
19 | 3.create DemoListFragment.java:
20 | ```Java
21 | public class DemoListFragment extends Fragment implements InnerScrollerContainer {
22 | protected View viewThis;
23 | protected InnerListView mListView;
24 |
25 | @Override
26 | public InnerScroller getInnerScroller() {
27 | return mListView;
28 | }
29 |
30 | @Override
31 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
32 | if (mListView != null && viewThis != null) {
33 | if (viewThis.getParent() != null) {
34 | ((ViewGroup) viewThis.getParent()).removeView(viewThis);
35 | }
36 | return viewThis;
37 | }
38 | viewThis = inflater.inflate(R.layout.fragment_list, null);
39 | mListView = (InnerListView) viewThis.findViewById(R.id.listView);
40 | mListView.setSelector(new ColorDrawable(Color.TRANSPARENT));
41 | mListView.setDividerHeight(0);
42 |
43 | mListView.register2Outer(mOuterScroller, mIndex);
44 |
45 | TODO: do something about your adapter and data
46 |
47 | return viewThis;
48 | }
49 |
50 | ...
51 |
52 | }
53 | ```
54 | You need to do something about your adapter and data.
55 |
56 | 4.Build your DemoPagerAdapter. Create a class DemoPagerAdapter, let it implement interface OutPagerAdapter and contains code below is enough for MagicHeaderViewPager.
57 |
58 | ```Java
59 | public class DemoPagerAdapter extends FragmentPagerAdapter implements OuterPagerAdapter{
60 |
61 | private OuterScroller mOuterScroller;
62 |
63 | @Override
64 | public void setOuterScroller(OuterScroller outerScroller) {
65 | mOuterScroller = outerScroller;
66 | }
67 |
68 | @Override
69 | public Object instantiateItem(ViewGroup container, int position) {
70 | InnerScrollerContainer fragment =
71 | (InnerScrollerContainer) super.instantiateItem(container, position);
72 |
73 | if (null != mOuterScroller) {
74 | fragment.setOuterScroller(mOuterScroller, position);
75 | }
76 | return fragment;
77 | }
78 |
79 | protected CharSequence[] mTitles = {"page 1", "page 2", "page 3", "page 4", "page 5", "page 6"};
80 |
81 | @Override
82 | public CharSequence getPageTitle(int position) {
83 | return mTitles[position];
84 | }
85 |
86 | @Override
87 | public int getCount() {
88 | return mTitles.length;
89 | }
90 |
91 | @Override
92 | public final Fragment getItem(int position) {
93 | return new DemoListFragment();
94 | }
95 |
96 | ...
97 |
98 | }
99 | ```
100 |
101 | 5.Add follow code into your DemoActivity's onCreate(Bundle) :
102 |
103 | ```Java
104 | mMagicHeaderViewPager = new MagicHeaderViewPager(this) {
105 | @Override
106 | protected void initTabsArea(LinearLayout container) {
107 | PagerSlidingTabStrip pagerSlidingTabStrip = new PagerSlidingTabStrip(XActivity.this);
108 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
109 | MagicHeaderUtils.dp2px(DemoActivity.this, 48));
110 | container.addView(pagerSlidingTabStrip, lp);
111 | setTabsArea(pagerSlidingTabStrip);
112 | setPagerSlidingTabStrip(pagerSlidingTabStrip);
113 | }
114 | };
115 | LinearLayout mhvpParent = (LinearLayout) findViewById(R.id.mhvp_parent);
116 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
117 | LinearLayout.LayoutParams.MATCH_PARENT,
118 | LinearLayout.LayoutParams.MATCH_PARENT
119 | );
120 | mhvpParent.addView(mMagicHeaderViewPager, lp);
121 | mPagerAdapter = new DemoPagerAdapter(getSupportFragmentManager());
122 | mMagicHeaderViewPager.setPagerAdapter(mPagerAdapter);
123 | ```
124 |
125 | "R.id.mhvp_parent" is id of the parent you want magicHeaderViewPager attach to. Usually to let the root view in your activity's layout xml like this is Ok.
126 | ```Xml
127 | \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
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 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file is automatically generated by Android Studio.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 | #
7 | # Location of the SDK. This is only used by Gradle.
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | #Wed Dec 23 18:36:40 CST 2015
11 | sdk.dir=/Applications/eclipse-ADT/android-sdk-macosxs
12 |
--------------------------------------------------------------------------------
/mhvp-core/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/mhvp-core/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 21
5 | buildToolsVersion '23.0.2'
6 | defaultConfig {
7 | minSdkVersion 7
8 | targetSdkVersion 21
9 | versionCode 1
10 | versionName "1.0"
11 | }
12 | buildTypes {
13 | release {
14 | minifyEnabled false
15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
16 | }
17 | }
18 | dependencies {
19 | compile 'com.android.support:support-v4:21.0.3'
20 | }
21 | lintOptions {
22 | abortOnError false
23 | }
24 | productFlavors {
25 | }
26 | }
27 |
28 | dependencies {
29 | compile fileTree(dir: 'libs', include: ['*.jar'])
30 | }
31 |
32 |
33 | // export aar
34 |
35 | //apply plugin: 'com.github.dcendents.android-maven'
36 | //apply plugin: 'com.jfrog.bintray'
37 | //
38 | //version = "2.1.2"
39 | //
40 | //def siteUrl = 'https://github.com/CuliuDev/MagicHeaderViewPager'
41 | //def gitUrl = 'https://github.com/CuliuDev/MagicHeaderViewPager.git'
42 | //
43 | //group = "com.culiu.android"
44 | //
45 | //install {
46 | // repositories.mavenInstaller {
47 | // // This generates POM.xml with proper parameters
48 | // pom {
49 | // project {
50 | // packaging 'aar'
51 | // name 'Magic Header ViewPager Core Lib'
52 | // url siteUrl
53 | // licenses {
54 | // license {
55 | // name 'The Apache Software License, Version 2.0'
56 | // url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
57 | // }
58 | // }
59 | // developers {
60 | // developer {
61 | // id 'Xavier.S'
62 | // name 'Xavier.S'
63 | // email 'X.S.Xavier.S@gmail.com'
64 | // }
65 | // }
66 | // scm {
67 | // connection gitUrl
68 | // developerConnection gitUrl
69 | // url siteUrl
70 | // }
71 | // }
72 | // }
73 | // }
74 | //}
75 | //
76 | //task sourcesJar(type: Jar) {
77 | // from android.sourceSets.main.java.srcDirs
78 | // classifier = 'sources'
79 | //}
80 | //
81 | //
82 | //task javadoc(type: Javadoc) {
83 | // source = android.sourceSets.main.java.srcDirs
84 | // options.charSet = 'UTF-8'
85 | // classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
86 | //}
87 | //
88 | //task javadocJar(type: Jar, dependsOn: javadoc) {
89 | // classifier = 'javadoc'
90 | // from javadoc.destinationDir
91 | //}
92 | //
93 | //artifacts {
94 | // archives javadocJar
95 | // archives sourcesJar
96 | //}
97 | //
98 | //Properties properties = new Properties()
99 | //properties.load(project.rootProject.file('local.properties').newDataInputStream())
100 | //bintray {
101 | // user = properties.getProperty("bintray.user")
102 | // key = properties.getProperty("bintray.apikey")
103 | // configurations = ['archives']
104 | // pkg {
105 | // repo = "maven"
106 | // name = "mhvp-core"
107 | // websiteUrl = siteUrl
108 | // vcsUrl = gitUrl
109 | // licenses = ["Apache-2.0"]
110 | // publish = true
111 | // }
112 | //}
--------------------------------------------------------------------------------
/mhvp-core/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Applications/eclipse-ADT/android-sdk-macosxs/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/mhvp-core/src/androidTest/java/com/culiu/mhvp/core/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.core;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/mhvp-core/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/java/com/culiu/mhvp/core/InnerScroller.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.core;
2 |
3 | import android.view.View;
4 |
5 |
6 | /**
7 | * @author Xavier-S
8 | * @date 2015.07.20
9 | */
10 | public interface InnerScroller {
11 |
12 | /**
13 | * (as its name)
14 | * {@hide}
15 | */
16 | void triggerOuterScroll();
17 |
18 | /**
19 | * (as its name)
20 | * @param firstVisibleItem
21 | * {@hide}
22 | */
23 | void recordScrollPosition(int firstVisibleItem);
24 |
25 | /**
26 | * Called by OuterScroller. verification inside. And will not directly produce scrolling. It will call performScroll() to produce substantial rolling.
27 | * {@hide}
28 | */
29 | void syncScroll();
30 | /**
31 | * (as its name)
32 | * {@hide}
33 | */
34 | void adjustEmptyHeaderHeight();
35 |
36 | /************** Methods for use both in and out ****************/
37 |
38 | /**
39 | * {@hide}
40 | */
41 | int getInnerScrollY();
42 |
43 |
44 | /********* Methods exploded for customization *************/
45 | OuterScroller getOuterScroller();
46 |
47 | /**
48 | * Everytime when you initialize and innerScroller, you must
49 | * call register2Outer(), or else this innerScroller would act
50 | * like ordinary Scroller(ListView/ScrollView).
51 | * @param mOuterScroller
52 | * @param mIndex
53 | */
54 | void register2Outer(OuterScroller mOuterScroller, int mIndex);
55 |
56 | /**
57 | * Get the view to receive touch event. Defaults to this.
58 | * @return
59 | */
60 | View getReceiveView();
61 |
62 | /**
63 | * (as its name)
64 | */
65 | void scrollToTop();
66 |
67 | /**
68 | * (as its name)
69 | * @return
70 | */
71 | boolean isScrolling();
72 |
73 | /**
74 | * Scroll to innerScroller's top.
75 | */
76 | void scrollToInnerTop();
77 |
78 | /**
79 | * Add inner header view
80 | * @param headerView
81 | */
82 | void addHeaderView(View headerView);
83 |
84 | /**
85 | * Callback to be implemented to inform OuterScroller
86 | * @param isRefreshing
87 | */
88 | void onRefresh(boolean isRefreshing);
89 |
90 | /**
91 | * Customize empty content view
92 | * @param emptyView
93 | */
94 | void setCustomEmptyView(View emptyView);
95 |
96 | /**
97 | * Customize empty content view's height.
98 | * @param height
99 | * @param offset
100 | */
101 | void setCustomEmptyViewHeight(int height, int offset);
102 |
103 | /**
104 | * Customize color of auto completion.
105 | * @param color
106 | */
107 | void setContentAutoCompletionColor(int color);
108 | }
109 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/java/com/culiu/mhvp/core/InnerScrollerContainer.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.core;
2 |
3 | /**
4 | * InnerScroller's Container,
5 | * which Fragment that contains a InnerScroller must implements.
6 | * @author Xavier-S
7 | * @date 2015.07.23
8 | */
9 | public interface InnerScrollerContainer {
10 |
11 | void setOuterScroller(OuterScroller outerScroller, int myPosition);
12 |
13 | InnerScroller getInnerScroller();
14 | }
15 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/java/com/culiu/mhvp/core/MagicHeaderUtils.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.core;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.graphics.drawable.Drawable;
6 | import android.os.SystemClock;
7 | import android.util.DisplayMetrics;
8 | import android.util.Log;
9 | import android.view.MotionEvent;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.view.WindowManager;
13 | import android.widget.FrameLayout;
14 |
15 | import java.util.ArrayList;
16 |
17 |
18 | /**
19 | * @author Xavier-S
20 | * @date 2015.07.21
21 | */
22 | public class MagicHeaderUtils {
23 |
24 | public static final String TAG = "sz[MagicHeaderUtils]";
25 |
26 | /******************** Inner Tool Methods ***********************/
27 | /**
28 | * (as its name)
29 | * @param value
30 | * @param base
31 | * @return
32 | */
33 | public static int calcDelta(int value, int base) {
34 | return value - base;
35 | }
36 |
37 | /**
38 | * Get a drawable's fit height when width == Screen_Width
39 | * @param context
40 | * @param drawable
41 | * @return
42 | */
43 | public static int getHeightWhenFullWidth(Context context, Drawable drawable) {
44 | return (int) (1f * MagicHeaderUtils.getScreenWidth(context) / drawable.getIntrinsicWidth() * drawable.getIntrinsicHeight());
45 | }
46 |
47 | /**
48 | * (as its name)
49 | * @param context
50 | * @param drawableId
51 | * @return
52 | */
53 | public static int getHeightWhenFullWidth(Context context, int drawableId) {
54 | return getHeightWhenFullWidth(context, context.getResources().getDrawable(drawableId));
55 | }
56 |
57 | /**
58 | * Three ways to shift View: margin of LayoutParams, setTransitionX/Y, View's Scroll.
59 | * Note: if minSDK > 2.3, using SET_TRANSLATION is ok without nineOldAndroids dependency.
60 | * if min SDK <= 2.3, suggest use LAYOUT_PARAMS or View's Scroll.)
61 | *
62 | */
63 | public interface TranslationMethods {
64 | int LAYOUT_PARAMS = 0;
65 | int SET_TRANSLATION = 1;
66 | int VIEW_SCROLL = 2;
67 | }
68 |
69 | /**
70 | * (as its name)
71 | * @param view
72 | * @param translation_Y Positive when upwards
73 | * @param translationMethod
74 | * @return true if success
75 | */
76 | @SuppressLint("NewApi")
77 | public static boolean setParamY(View view, int translation_Y, int translationMethod) {
78 | if (view == null) {
79 | Log.e(TAG, "ERROR: warning: your params contains null in setParamY()");
80 | return false;
81 | }
82 | boolean result;
83 | switch (translationMethod) {
84 | case TranslationMethods.VIEW_SCROLL:
85 | if(translation_Y != view.getScrollY()) {
86 | view.scrollTo(0, translation_Y);
87 | result = true;
88 | } else {
89 | result = false;
90 | }
91 | break;
92 | case TranslationMethods.LAYOUT_PARAMS:
93 | translation_Y = -translation_Y;
94 | ViewGroup.LayoutParams lp = view.getLayoutParams();
95 | if (!(lp instanceof FrameLayout.LayoutParams)) {
96 | // Log.w(TAG, "Warning: view " + view + "'s parent must be FrameLayout T.T");
97 | return false;
98 | }
99 | FrameLayout.LayoutParams fl_lp = (FrameLayout.LayoutParams) lp;
100 | if (translation_Y != fl_lp.topMargin) {
101 | fl_lp.topMargin = translation_Y;
102 | view.requestLayout();
103 | result = true;
104 | } else {
105 | result = false;
106 | }
107 | break;
108 | case TranslationMethods.SET_TRANSLATION:
109 | translation_Y = -translation_Y;
110 | view.setTranslationY(translation_Y);
111 | result = true;
112 | break;
113 | default:
114 | Log.e(TAG, "ERROR:Sorry. in setParamY, what is your TranslationMethods?");
115 | result = false;
116 | }
117 | return result;
118 | }
119 |
120 | /**
121 | * (as its name).
122 | * @param view
123 | * @param translationMethod
124 | * @return Y value, positive when upwards
125 | */
126 | @SuppressLint("NewApi")
127 | public static float getParamY(View view, int translationMethod) {
128 | float result = 0f;
129 | if(view == null) {
130 | return result;
131 | }
132 | switch (translationMethod) {
133 | case TranslationMethods.VIEW_SCROLL:
134 | result = view.getScrollY();
135 | break;
136 | case TranslationMethods.LAYOUT_PARAMS:
137 | ViewGroup.LayoutParams lp = view.getLayoutParams();
138 | if (!(lp instanceof FrameLayout.LayoutParams)) {
139 | Log.e(TAG, "Sorry, view " + view + "'s parent must be FrameLayout T.T");
140 | return 0;
141 | }
142 | FrameLayout.LayoutParams fl_lp = (FrameLayout.LayoutParams) lp;
143 | result = -fl_lp.topMargin;
144 | break;
145 | case TranslationMethods.SET_TRANSLATION:
146 | result = view.getTranslationY();
147 | break;
148 |
149 | }
150 | return result;
151 | }
152 |
153 | /**
154 | * (as its name)
155 | */
156 | public static float clamp(float value, float min, float max) {
157 |
158 | if(min > max) {
159 | return value;
160 | }
161 | return Math.min(Math.max(value, min), max);
162 | }
163 |
164 | /**
165 | * Convert dp to px
166 | */
167 | public static int dp2px(Context context, float dpValue) {
168 | final float scale = context.getResources().getDisplayMetrics().density;
169 | return (int) (dpValue * scale + 0.5f);
170 | }
171 |
172 | /**
173 | * Convert px to dp
174 | */
175 | public static int px2dp(Context context, float pxValue) {
176 | final float scale = context.getResources().getDisplayMetrics().density;
177 | return (int) (pxValue / scale + 0.5f);
178 | }
179 |
180 | /**
181 | * (as its name)
182 | */
183 | public static int getScreenWidth(Context context) {
184 | WindowManager wm = (WindowManager) context
185 | .getSystemService(Context.WINDOW_SERVICE);
186 | DisplayMetrics outMetrics = new DisplayMetrics();
187 | wm.getDefaultDisplay().getMetrics(outMetrics);
188 | return outMetrics.widthPixels;
189 | }
190 |
191 | /**
192 | * (as its name)
193 | */
194 | public static int getScreenHeight(Context context) {
195 | WindowManager wm = (WindowManager) context
196 | .getSystemService(Context.WINDOW_SERVICE);
197 | DisplayMetrics outMetrics = new DisplayMetrics();
198 | wm.getDefaultDisplay().getMetrics(outMetrics);
199 | return outMetrics.heightPixels;
200 | }
201 |
202 | /**
203 | * Dispatch a CANCEL event to view, force to stop responding to any touch event.
204 | * @param view
205 | */
206 | public static void cancelTouchEvent(View view) {
207 | final long now = SystemClock.uptimeMillis();
208 | MotionEvent event = MotionEvent.obtain(now, now,
209 | MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
210 | view.dispatchTouchEvent(event);
211 | event.recycle();
212 | }
213 |
214 | /**
215 | * @param view
216 | * @param event_source
217 | * @param actionType System will reuse the event object, so actionType is also needed.
218 | */
219 | public static final boolean copyAndDispatchTouchEvent(View view, MotionEvent event_source, int actionType) {
220 | final long now = SystemClock.uptimeMillis();
221 | MotionEvent event = MotionEvent.obtain(now, now,
222 | actionType, event_source.getX(), event_source.getY(), event_source.getMetaState());
223 | boolean result = view.dispatchTouchEvent(event);
224 | event.recycle();
225 | return result;
226 | }
227 |
228 | /********************* ArrayList Tool Method *************************/
229 |
230 | public static void ensureCapacityWithEmptyObject(ArrayList arrayList, int capacity, Class clazz) {
231 |
232 | if(arrayList == null) {
233 | arrayList = new ArrayList();
234 | }
235 |
236 | int delta = capacity - arrayList.size();
237 |
238 | if(delta <= 0) {
239 | return;
240 | }
241 |
242 | arrayList.ensureCapacity(capacity);
243 | try {
244 | for(;delta > 0; delta--) {
245 | arrayList.add(clazz.newInstance());
246 | }
247 | } catch (InstantiationException e) {
248 | e.printStackTrace();
249 | } catch (IllegalAccessException e) {
250 | e.printStackTrace();
251 | }
252 |
253 | }
254 | }
255 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/java/com/culiu/mhvp/core/OuterPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.core;
2 |
3 | /**
4 | * Interface of MagicHeaderViewPager's Adapter.
5 | * Use a FragmentPagerAdapter class to implement like this:
6 | *
7 | *
8 | * ```
9 | * public class DemoPagerAdapter extends FragmentPagerAdapter implements OuterPagerAdapter {
10 | *
11 | *
12 | * ...
13 | *
14 | * private OuterScroller mOuterScroller;
15 | *
16 | * public void setOuterScroller(OuterScroller outerScroller) {
17 | *
18 | * mOuterScroller = outerScroller;
19 | *
20 | * }
21 | *
22 | * public Object instantiateItem(ViewGroup container, int position) {
23 | *
24 | * // TODO: Make sure to put codes below in your PagerAdapter's instantiateItem()
25 | * // cuz Fragment has some weird life cycle.
26 | * InnerScrollerContainer fragment =
27 | *
28 | * (InnerScrollerContainer) super.instantiateItem(container, position);
29 | *
30 | *
31 | * if (null != mOuterScroller) {
32 | *
33 | * fragment.setOuterScroller(mOuterScroller, position);
34 | *
35 | * }
36 | * return fragment;
37 | *
38 | * }
39 | *
40 | *
41 | * ...
42 | *
43 | *
44 | * }
45 | * ```
46 | * @date 2015.07.23
47 | */
48 | public interface OuterPagerAdapter {
49 |
50 | void setOuterScroller(OuterScroller outerScroller);
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/java/com/culiu/mhvp/core/OuterScroller.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.core;
2 |
3 | import android.support.v4.view.ViewPager;
4 | import android.view.View;
5 |
6 | /**
7 | * @author Xavier-S
8 | * @date 2015.07.20
9 | */
10 | public interface OuterScroller extends ViewPager.OnPageChangeListener {
11 |
12 | /**
13 | * Callback form current innerScroller scroll.
14 | * @param pageIndex
15 | * @param scrollY InnerScroller's scrollY
16 | * {@hide}
17 | */
18 | void onInnerScroll(int pageIndex, int scrollY);
19 |
20 | /**
21 | * (as its name)
22 | * {@hide}
23 | */
24 | void onPageSelected(int position);
25 |
26 | /**
27 | * Get overall height of header
28 | * @return
29 | */
30 | int getHeaderHeight();
31 |
32 | /**
33 | * Get magic header's visible height.
34 | * @return
35 | */
36 | int getHeaderVisibleHeight();
37 |
38 | /**
39 | * Synchronize Header scroll position. It can be enormously called. With many verification
40 | * inside, innerScrollers won't perform scroll unless necessary.
41 | *
42 | * @param currentIndex Current index,also is the excluded index in synchronization.
43 | * {@hide}
44 | */
45 | void syncPagesPosition(int currentIndex);
46 |
47 |
48 | /**
49 | * (as its name)
50 | * @return
51 | */
52 | InnerScroller getCurrentInnerScroller();
53 |
54 | /**
55 | * (as its name)
56 | * @return
57 | */
58 | int getCurrentInnerScrollerIndex();
59 |
60 | /**
61 | * Add custom HeaderView
62 | * @param view
63 | */
64 | void addHeaderView(View view);
65 |
66 | /**
67 | * (as its name)
68 | * {@hide}
69 | */
70 | void adjustChildrenEmptyHeaderHeight();
71 |
72 | /**
73 | * Callback on current InnerScroller stop scrolling.
74 | * {@hide}
75 | */
76 | void onInnerScrollerStop();
77 |
78 | /**
79 | * @param index
80 | * @param innerScroller
81 | * {@hide}
82 | */
83 | void registerInnerScroller(int index, InnerScroller innerScroller);
84 |
85 |
86 | /************************ 内外刷新联动 **************************/
87 |
88 | /**
89 | * Callback of InnerScroller's PullToRefresh
90 | * @param scrollY
91 | */
92 | void onInnerPullToRefreshScroll(int scrollY);
93 |
94 | /**
95 | * Get content visible area max height, equals to (view Height - stable area height)
96 | * @return
97 | */
98 | int getContentAreaMaxVisibleHeight();
99 |
100 | /**
101 | * Update state of refresh.
102 | * @param isRefreshing the coming state
103 | * {@hide}
104 | */
105 | void updateRefreshState(boolean isRefreshing);
106 |
107 | /******************* unused methods from OnPageChangeListener ********************/
108 | /**
109 | * No need to do anything here
110 | * @param state
111 | * {@hide}
112 | */
113 | @Deprecated
114 | void onPageScrollStateChanged(int state);
115 |
116 | /**
117 | * No need to do anything here
118 | * @param position
119 | * @param positionOffset
120 | * @param positionOffsetPixels
121 | * {@hide}
122 | */
123 | @Deprecated
124 | void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
125 |
126 | }
--------------------------------------------------------------------------------
/mhvp-core/src/main/java/com/culiu/mhvp/core/ScrollableViewPager.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.core;
2 |
3 | import android.content.Context;
4 | import android.support.v4.view.ViewPager;
5 | import android.util.AttributeSet;
6 | import android.view.MotionEvent;
7 |
8 | /**
9 | * @author Xavier-S
10 | * @date 2015.11.16 15:16
11 | */
12 | public class ScrollableViewPager extends ViewPager {
13 |
14 | public ScrollableViewPager(Context context) {
15 | super(context);
16 | }
17 |
18 | public ScrollableViewPager(Context context, AttributeSet attrs) {
19 | super(context, attrs);
20 | }
21 |
22 | boolean mScrollable = true;
23 |
24 |
25 | public boolean isScrollable() {
26 | return mScrollable;
27 | }
28 |
29 | public void setScrollable(boolean scrollable) {
30 | this.mScrollable = scrollable;
31 | }
32 |
33 | @Override
34 | public boolean onInterceptTouchEvent(MotionEvent ev) {
35 | if(mScrollable) {
36 | return super.onInterceptTouchEvent(ev);
37 | } else {
38 | return false;
39 | }
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/java/com/culiu/mhvp/core/layout/SizeSensitiveLinearLayout.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.core.layout;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.util.Log;
6 | import android.widget.LinearLayout;
7 |
8 | /**
9 | * A LinearLayout, its onSizeChanged() in mSizeChangedListener will be called
10 | * When sizeChanged.
11 | * @author Xavier-S
12 | * @date 2015.07.23
13 | */
14 | public class SizeSensitiveLinearLayout extends LinearLayout {
15 |
16 | public static final String TAG = "sz[SSLL]";
17 |
18 | private SizeChangedListener mSizeChangedListener;
19 |
20 | public SizeSensitiveLinearLayout(Context context) {
21 | super(context);
22 | }
23 |
24 | public SizeSensitiveLinearLayout(Context context, AttributeSet attrs) {
25 | super(context, attrs);
26 | }
27 |
28 | @Override
29 | protected void onAttachedToWindow() {
30 | super.onAttachedToWindow();
31 | }
32 |
33 | @Override
34 | protected void onDetachedFromWindow() {
35 | super.onDetachedFromWindow();
36 | }
37 |
38 | @Override
39 | protected void onSizeChanged(int w, int h, int oldw, int oldh) {
40 | super.onSizeChanged(w, h, oldw, oldh);
41 | if(mSizeChangedListener != null) {
42 | mSizeChangedListener.onSizeChanged(w, h, oldw, oldh);
43 | }
44 | }
45 |
46 | public void setOnSizeChangedListener(SizeChangedListener sizeChangedListener) {
47 | mSizeChangedListener = sizeChangedListener;
48 | }
49 |
50 | public interface SizeChangedListener {
51 | void onSizeChanged(int w, int h, int oldw, int oldh);
52 | }
53 |
54 | @Override
55 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
56 | heightMeasureSpec = MeasureSpec.UNSPECIFIED;
57 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/java/com/culiu/mhvp/core/layout/TranslatableLinearLayout.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.core.layout;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.os.Build;
6 | import android.util.AttributeSet;
7 | import android.view.MotionEvent;
8 | import android.widget.LinearLayout;
9 |
10 | import com.culiu.mhvp.core.MagicHeaderViewPager;
11 |
12 | /**
13 | * A LinearLayout that act as it can translation in Y,
14 | * while actually it didn't.
15 | * {@hide}
16 | * @author Xavier-S
17 | * @date 2015.08.11
18 | */
19 | public class TranslatableLinearLayout extends LinearLayout {
20 |
21 | public static final String TAG = "sz[TLL]";
22 | private MagicHeaderViewPager mMagicHeaderViewPager;
23 |
24 | public TranslatableLinearLayout(Context context) {
25 | super(context);
26 | }
27 |
28 | public TranslatableLinearLayout(Context context, AttributeSet attrs) {
29 | super(context, attrs);
30 | }
31 |
32 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
33 | public TranslatableLinearLayout(Context context, AttributeSet attrs, int defStyle) {
34 | super(context, attrs, defStyle);
35 | }
36 |
37 | @Override
38 | protected void onAttachedToWindow() {
39 | super.onAttachedToWindow();
40 | initView();
41 | }
42 |
43 | private void initView() {
44 | if(getParent()!=null) {
45 | mMagicHeaderViewPager = (MagicHeaderViewPager)getParent();
46 | }
47 | }
48 |
49 | @Override
50 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
51 | if(mMagicHeaderViewPager!= null && mMagicHeaderViewPager.isHeaderTallerThanScreen()) {
52 | heightMeasureSpec = MeasureSpec.UNSPECIFIED;
53 | }
54 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
55 | }
56 |
57 | private boolean mProcessTouchEvent;
58 |
59 | /**
60 | * 对控件内的触摸进行分发控制,让它只处理看起来的边界内的事件
61 | * (control the touch event in this view, to let it
62 | * just deal with event located in area where this looks)
63 | */
64 | @Override
65 | public boolean dispatchTouchEvent(MotionEvent ev) {
66 | int visualBottom = getVisualBottom();
67 | switch(ev.getAction()) {
68 | case MotionEvent.ACTION_DOWN:
69 | if(ev.getY() < visualBottom && !mMagicHeaderViewPager.intercept2InnerScroller) {
70 | mProcessTouchEvent = true;
71 | return super.dispatchTouchEvent(ev);
72 | } else {
73 | mProcessTouchEvent = false;
74 | return false;
75 | }
76 | case MotionEvent.ACTION_MOVE:
77 | if(mProcessTouchEvent) {
78 | if( !mMagicHeaderViewPager.intercept2InnerScroller) {
79 | return super.dispatchTouchEvent(ev);
80 | } else {
81 | mProcessTouchEvent = false;
82 | return false;
83 | }
84 | } else {
85 | return false;
86 | }
87 | case MotionEvent.ACTION_UP:
88 | if(mProcessTouchEvent && !mMagicHeaderViewPager.intercept2InnerScroller) {
89 | return super.dispatchTouchEvent(ev);
90 | } else {
91 | return false;
92 | }
93 | case MotionEvent.ACTION_CANCEL:
94 | if(mProcessTouchEvent) {
95 | mProcessTouchEvent = false;
96 | }
97 | return super.dispatchTouchEvent(ev);
98 | default:
99 | return false;
100 | }
101 | }
102 |
103 | public int getVisualBottom() {
104 | return getBottom() - getScrollY();
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/java/com/culiu/mhvp/core/specialview/InnerSpecialViewHelper.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.core.specialview;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import com.culiu.mhvp.core.MagicHeaderUtils;
9 | import com.culiu.mhvp.core.OuterScroller;
10 | import com.culiu.mhvp.core.R;
11 |
12 | /**
13 | * Helper of special views in InnerScroller.
14 | * @author Xavier-S
15 | * @date 2015.11.17 15:07
16 | */
17 | public class InnerSpecialViewHelper {
18 |
19 | View mInnerEmptyView;
20 |
21 | private View mCustomEmptyView;
22 |
23 | Context mContext;
24 | OuterScroller mOuterScroller;
25 |
26 | public InnerSpecialViewHelper(Context context) {
27 | mContext = context;
28 | }
29 |
30 | public View getCustomEmptyView() {
31 | return mCustomEmptyView;
32 | }
33 |
34 | public View getInnerEmptyView() {
35 | if(mCustomEmptyView != null) {
36 | return mCustomEmptyView;
37 | }
38 | return mInnerEmptyView;
39 | }
40 |
41 | public void setInnerEmptyView(View innerEmptyView) {
42 | mInnerEmptyView = innerEmptyView;
43 | }
44 |
45 | public View getInnerEmptyViewSafely() {
46 | if(mCustomEmptyView != null) {
47 | return mCustomEmptyView;
48 | }
49 | if(mInnerEmptyView != null) {
50 | return mInnerEmptyView;
51 | }
52 | mInnerEmptyView = new View(mContext);
53 | return mInnerEmptyView;
54 | }
55 |
56 |
57 | public int getInnerEmptyViewHeightSafely() {
58 | int result;
59 | switch (mCustomEmptyViewHeight) {
60 | case ViewGroup.LayoutParams.WRAP_CONTENT:
61 | result = getInnerEmptyViewSafely().getMeasuredHeight();
62 | break;
63 | case ViewGroup.LayoutParams.MATCH_PARENT:
64 | if (mOuterScroller != null) {
65 | result = mOuterScroller.getContentAreaMaxVisibleHeight();
66 | } else {
67 | result = MagicHeaderUtils.getScreenHeight(mContext);
68 | }
69 | break;
70 | default:
71 | result = mCustomEmptyViewHeight;
72 | }
73 | result += mCustomEmptyViewHeightOffset;
74 |
75 | // height result may not be larger than outers ContentAreaMaxVisibleHeight.
76 | // in case of listview position error after notifyDataSetChanged().
77 | result = Math.min(result, mOuterScroller.getContentAreaMaxVisibleHeight());
78 |
79 | return result;
80 | }
81 |
82 | public void setOuterScroller(OuterScroller outerScroller) {
83 | mOuterScroller = outerScroller;
84 | }
85 |
86 | /******** Inner Empty View Customization *************/
87 |
88 | public void setCustomEmptyView(View customEmptyView) {
89 | mCustomEmptyView = customEmptyView;
90 | mInnerEmptyView = mCustomEmptyView;
91 | }
92 |
93 | private int mCustomEmptyViewHeight = ViewGroup.LayoutParams.MATCH_PARENT;
94 | private int mCustomEmptyViewHeightOffset;
95 |
96 | public void setCustomEmptyViewHeight(int height, int offset) {
97 | mCustomEmptyViewHeight = height;
98 | mCustomEmptyViewHeightOffset = offset;
99 | }
100 |
101 |
102 | /************* Content Auto Completion View *****************/
103 |
104 | public View mContentAutoCompletionView;
105 |
106 | int mContentAutoCompletionColor = ORIGIN_AUTO_COMPLETION_COLOR;
107 |
108 | public View getContentAutoCompletionView() {
109 | return mContentAutoCompletionView;
110 | }
111 |
112 | public View getContentAutoCompletionViewSafely() {
113 | if(mContentAutoCompletionView == null) {
114 | generateContentAutoCompletionView();
115 | }
116 | return mContentAutoCompletionView;
117 | }
118 |
119 | public void setContentAutoCompletionView(View contentAutoCompletionView) {
120 | mContentAutoCompletionView = contentAutoCompletionView;
121 | }
122 |
123 | private static final int ORIGIN_AUTO_COMPLETION_COLOR = Color.TRANSPARENT;
124 |
125 | public void setContentAutoCompletionColor(int color) {
126 | getContentAutoCompletionViewSafely().setBackgroundColor(mContentAutoCompletionColor = color);
127 | }
128 |
129 | public View generateContentAutoCompletionView() {
130 | mContentAutoCompletionView = new View(mContext);
131 | mContentAutoCompletionView.setTag(R.id.id_for_auto_completion_content, "");
132 | if(mContentAutoCompletionColor != ORIGIN_AUTO_COMPLETION_COLOR) {
133 | mContentAutoCompletionView.setBackgroundColor(mContentAutoCompletionColor);
134 | }
135 | return mContentAutoCompletionView;
136 | }
137 |
138 | private int mContentAutoCompletionViewOffset;
139 |
140 | public void setContentAutoCompletionViewOffset(int offset) {
141 | mContentAutoCompletionViewOffset = offset;
142 | }
143 |
144 | public int getContentAutoCompletionViewOffset() {
145 | return mContentAutoCompletionViewOffset;
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/java/com/culiu/mhvp/core/tabs/GridViewWithHeaderBaseAdapter.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.core.tabs;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.view.View.OnClickListener;
6 | import android.view.ViewGroup;
7 | import android.view.ViewGroup.LayoutParams;
8 | import android.widget.BaseAdapter;
9 | import android.widget.LinearLayout;
10 |
11 |
12 | public abstract class GridViewWithHeaderBaseAdapter extends BaseAdapter {
13 |
14 | public interface GridItemClickListener {
15 |
16 | void onGridItemClicked(View v, int position, long itemId);
17 |
18 | }
19 |
20 | private class ListItemClickListener implements OnClickListener {
21 |
22 | private int mPosition;
23 |
24 | public ListItemClickListener(int currentPos) {
25 | mPosition = currentPos;
26 | }
27 |
28 | @Override
29 | public void onClick(View v) {
30 | onGridItemClicked(v, mPosition);
31 | }
32 | }
33 |
34 | private int mNumColumns;
35 |
36 | protected Context mContext;
37 |
38 | private GridItemClickListener mGridItemClickListener;
39 |
40 | public GridViewWithHeaderBaseAdapter(Context context) {
41 | mContext = context;
42 | mNumColumns = 1;
43 | }
44 |
45 | public final void setOnGridClickListener(GridItemClickListener listener) {
46 | mGridItemClickListener = listener;
47 | }
48 |
49 | private final void onGridItemClicked(View v, int position) {
50 | if(mGridItemClickListener != null) {
51 | mGridItemClickListener.onGridItemClicked(v, position, getItemId(position));
52 | }
53 | }
54 |
55 | public final int getNumColumns() {
56 | return mNumColumns;
57 | }
58 |
59 | public final void setNumColumns(int numColumns) {
60 | mNumColumns = numColumns;
61 | notifyDataSetChanged();
62 | }
63 |
64 | @Override
65 | public boolean areAllItemsEnabled() {
66 | return false;
67 | }
68 |
69 | @Override
70 | public boolean isEnabled(int position) {
71 | return false;
72 | }
73 |
74 | @Override
75 | public int getCount() {
76 | return (int) Math.ceil(getItemCount() * 1f / getNumColumns());
77 | }
78 |
79 | public abstract int getItemCount();
80 |
81 | protected abstract View getItemView(int position, View view, ViewGroup parent);
82 |
83 | @Override
84 | public View getView(int position, View view, ViewGroup viewGroup) {
85 | LinearLayout layout;
86 | int columnWidth = 0;
87 | if(viewGroup != null) {
88 | columnWidth = viewGroup.getWidth() / mNumColumns;
89 | } else if(view != null) {
90 | columnWidth = view.getWidth() / mNumColumns;
91 | }
92 | // Make it be rows of the number of columns
93 | if(view == null) {
94 | // This is items view
95 | layout = createItemRow(position, viewGroup, columnWidth);
96 | } else {
97 | layout = (LinearLayout)view;
98 | updateItemRow(position, viewGroup, layout, columnWidth);
99 | }
100 | return layout;
101 | }
102 |
103 | private LinearLayout createItemRow(int position, ViewGroup viewGroup, int columnWidth) {
104 | LinearLayout layout;
105 | layout = new LinearLayout(mContext);
106 | layout.setOrientation(LinearLayout.HORIZONTAL);
107 | // Now add the sub views to it
108 | View leftView = null, rightView = null;
109 | for(int i = 0; i < mNumColumns; i ++ ) {
110 | int currentPos = position * mNumColumns + i;
111 | // Get the new View
112 | View insideView;
113 | if(currentPos < getItemCount()) {
114 | insideView = getItemView(currentPos, null, viewGroup);
115 | insideView.setVisibility(View.VISIBLE);
116 | View theView = getItemView(currentPos, insideView, viewGroup);
117 | theView.setOnClickListener(new ListItemClickListener(currentPos));
118 | } else {
119 | insideView = getItemView(0, null, viewGroup);
120 | insideView.setVisibility(View.INVISIBLE);
121 | }
122 | if(i == 0) {
123 | leftView = insideView;
124 | } else {
125 | rightView = insideView;
126 | }
127 |
128 | layout.addView(insideView);
129 | // Set the width of this column
130 | LayoutParams params = insideView.getLayoutParams();
131 | params.width = columnWidth;
132 | params.height = LayoutParams.MATCH_PARENT;
133 | insideView.setLayoutParams(params);
134 | }
135 | setPaddingAndMargin(leftView, rightView, mNumColumns);
136 | return layout;
137 | }
138 |
139 | /**
140 | * @param leftView
141 | * @param rightView
142 | * @param culumn
143 | */
144 | protected void setPaddingAndMargin(View leftView, View rightView, int culumn) {
145 |
146 | }
147 |
148 | private void updateItemRow(int position, ViewGroup viewGroup, LinearLayout layout, int columnWidth) {
149 | for(int i = 0; i < mNumColumns; i ++ ) {
150 | int currentPos = position * mNumColumns + i;
151 | View insideView = layout.getChildAt(i);
152 | // If there are less views than objects. add a view here
153 | if(insideView == null) {
154 | insideView = new View(mContext);
155 | layout.addView(insideView);
156 | }
157 | // Set the width of this column
158 | LayoutParams params = insideView.getLayoutParams();
159 | params.width = columnWidth;
160 | insideView.setLayoutParams(params);
161 |
162 | if(currentPos < getItemCount()) {
163 | insideView.setVisibility(View.VISIBLE);
164 | // Populate the view
165 | View theView = getItemView(currentPos, insideView, viewGroup);
166 | if(insideView.getTag() == null) {
167 | layout.removeViewAt(i);
168 | layout.addView(theView, i);
169 | }
170 | theView.setOnClickListener(new ListItemClickListener(currentPos));
171 | if( ! theView.equals(insideView)) {
172 | // DO NOT CHANGE THE VIEWS
173 | }
174 | } else {
175 | insideView.setVisibility(View.INVISIBLE);
176 | }
177 | }
178 | }
179 | }
--------------------------------------------------------------------------------
/mhvp-core/src/main/java/com/culiu/mhvp/core/util/IntegerVariable.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.core.util;
2 |
3 | /**
4 | * 整形变量内。可直接改变里面的值,而不用修改对象引用。
5 | * (With an Integer inside. Can change value without changing reference.)
6 | */
7 | public final class IntegerVariable {
8 |
9 | private int mValue;
10 |
11 | public IntegerVariable(int value) {
12 | mValue = value;
13 | }
14 |
15 | public IntegerVariable() {
16 | }
17 |
18 | public final int getValue() {
19 | return mValue;
20 | }
21 |
22 | public final void setValue(int value) {
23 | mValue = value;
24 | }
25 |
26 | @Override
27 | public boolean equals(Object o) {
28 | // 地址
29 | if(this == o) {
30 | return true;
31 | }
32 |
33 | // 同类比较值
34 | if(o instanceof IntegerVariable) {
35 | return mValue == ((IntegerVariable)o).getValue();
36 | }
37 |
38 | // 异类比较值
39 | if(o instanceof Integer) {
40 | return mValue == ((Integer)o).intValue();
41 | }
42 |
43 | // 无法处理的,扔给父类
44 | return super.equals(o);
45 | }
46 |
47 | @Override
48 | public String toString() {
49 | return String.valueOf(mValue);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/res/drawable/background_tab.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/res/layout/mhvp_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
19 |
20 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | -->
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6633B5E5
4 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/res/values/psts_attr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/mhvp-core/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | mhvp-core
4 |
5 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 21
5 | buildToolsVersion '23.0.2'
6 | defaultConfig {
7 | minSdkVersion 7
8 | targetSdkVersion 21
9 | versionCode 1
10 | versionName "1.0"
11 | }
12 | buildTypes {
13 | release {
14 | minifyEnabled false
15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
16 | }
17 | }
18 | productFlavors {
19 | }
20 | }
21 |
22 | dependencies {
23 | compile project(':mhvp-core')
24 | }
25 |
26 | // export aar
27 |
28 | //apply plugin: 'com.github.dcendents.android-maven'
29 | //apply plugin: 'com.jfrog.bintray'
30 | //
31 | //version = "2.1.2"
32 | //
33 | //def siteUrl = 'https://github.com/CuliuDev/MagicHeaderViewPager'
34 | //def gitUrl = 'https://github.com/CuliuDev/MagicHeaderViewPager.git'
35 | //
36 | //group = "com.culiu.android"
37 | //
38 | //install {
39 | // repositories.mavenInstaller {
40 | // // This generates POM.xml with proper parameters
41 | // pom {
42 | // project {
43 | // packaging 'aar'
44 | // name 'Magic Header ViewPager Integrated Pull-To-Refresh Lib'
45 | // url siteUrl
46 | // licenses {
47 | // license {
48 | // name 'The Apache Software License, Version 2.0'
49 | // url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
50 | // }
51 | // }
52 | // developers {
53 | // developer {
54 | // id 'Xavier.S'
55 | // name 'Xavier.S'
56 | // email 'X.S.Xavier.S@gmail.com'
57 | // }
58 | // }
59 | // scm {
60 | // connection gitUrl
61 | // developerConnection gitUrl
62 | // url siteUrl
63 | // }
64 | // }
65 | // }
66 | // }
67 | //}
68 | //
69 | //task sourcesJar(type: Jar) {
70 | // from android.sourceSets.main.java.srcDirs
71 | // classifier = 'sources'
72 | //}
73 | //
74 | //
75 | //task javadoc(type: Javadoc) {
76 | // source = android.sourceSets.main.java.srcDirs
77 | // options.charSet = 'UTF-8'
78 | // classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
79 | //}
80 | //
81 | //task javadocJar(type: Jar, dependsOn: javadoc) {
82 | // classifier = 'javadoc'
83 | // from javadoc.destinationDir
84 | //}
85 | //
86 | //artifacts {
87 | // archives javadocJar
88 | // archives sourcesJar
89 | //}
90 | //
91 | //Properties properties = new Properties()
92 | //properties.load(project.rootProject.file('local.properties').newDataInputStream())
93 | //bintray {
94 | // user = properties.getProperty("bintray.user")
95 | // key = properties.getProperty("bintray.apikey")
96 | // configurations = ['archives']
97 | // pkg {
98 | // repo = "maven"
99 | // name = "mhvp-integrated-ptr"
100 | // websiteUrl = siteUrl
101 | // vcsUrl = gitUrl
102 | // licenses = ["Apache-2.0"]
103 | // publish = true
104 | // }
105 | //}
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Applications/eclipse-ADT/android-sdk-macosxs/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/androidTest/java/com/culiu/mhvp/integrated/ptr/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.integrated.ptr;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/java/com/culiu/mhvp/integrated/ptr/PullToRefreshInnerScrollView.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3 | * except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
4 | * required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing
6 | * permissions and limitations under the License.
7 | *******************************************************************************/
8 | package com.culiu.mhvp.integrated.ptr;
9 |
10 | import android.annotation.TargetApi;
11 | import android.content.Context;
12 | import android.os.Build.VERSION;
13 | import android.os.Build.VERSION_CODES;
14 | import android.util.AttributeSet;
15 | import android.view.View;
16 |
17 | import com.culiu.mhvp.integrated.ptr.pulltorefresh.PullToRefreshBase;
18 | import com.culiu.mhvp.integrated.ptr.R;
19 | import com.culiu.mhvp.integrated.ptr.pulltorefresh.OverscrollHelper;
20 | import com.culiu.mhvp.core.InnerScrollView;
21 |
22 | public class PullToRefreshInnerScrollView extends PullToRefreshBase {
23 |
24 | public PullToRefreshInnerScrollView(Context context) {
25 | super(context);
26 | }
27 |
28 | public PullToRefreshInnerScrollView(Context context, AttributeSet attrs) {
29 | super(context, attrs);
30 | }
31 |
32 | public PullToRefreshInnerScrollView(Context context, Mode mode) {
33 | super(context, mode);
34 | }
35 |
36 | public PullToRefreshInnerScrollView(Context context, Mode mode, AnimationStyle style) {
37 | super(context, mode, style);
38 | }
39 |
40 | @Override
41 | public final Orientation getPullToRefreshScrollDirection() {
42 | return Orientation.VERTICAL;
43 | }
44 |
45 | InnerScrollView scrollView;
46 | @Override
47 | protected InnerScrollView createRefreshableView(Context context, AttributeSet attrs) {
48 | if(VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
49 | scrollView=new InternalScrollViewSDK9(context, attrs);
50 | } else {
51 | scrollView=new InnerScrollView(context, attrs);
52 | }
53 |
54 | scrollView.setId(R.id.scrollview);
55 | // Set it so that it can be reached from InnerSroller -- Xavier-S
56 | scrollView.setReceiveView(this);
57 | return scrollView;
58 | }
59 |
60 | @Override
61 | protected boolean isReadyForPullStart() {
62 | return mRefreshableView.getScrollY() == 0;
63 | }
64 |
65 | @Override
66 | protected boolean isReadyForPullEnd() {
67 | View scrollViewChild=mRefreshableView.getChildAt(0);
68 | if(null != scrollViewChild) {
69 | return mRefreshableView.getScrollY() >= (scrollViewChild.getHeight() - getHeight());
70 | }
71 | return false;
72 | }
73 |
74 | @TargetApi(9)
75 | final class InternalScrollViewSDK9 extends InnerScrollView {
76 |
77 | public InternalScrollViewSDK9(Context context, AttributeSet attrs) {
78 | super(context, attrs);
79 | }
80 |
81 | @Override
82 | protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY,
83 | int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
84 |
85 | final boolean returnValue=
86 | super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY,
87 | isTouchEvent);
88 |
89 | // Does all of the hard work...
90 | OverscrollHelper.overScrollBy(PullToRefreshInnerScrollView.this, deltaX, scrollX, deltaY, scrollY, getScrollRange(),
91 | isTouchEvent);
92 |
93 | return returnValue;
94 | }
95 |
96 | /**
97 | * Taken from the AOSP ScrollView source
98 | */
99 | private int getScrollRange() {
100 | int scrollRange=0;
101 | if(getChildCount() > 0) {
102 | View child=getChildAt(0);
103 | scrollRange=Math.max(0, child.getHeight() - (getHeight() - getPaddingBottom() - getPaddingTop()));
104 | }
105 | return scrollRange;
106 | }
107 |
108 | @Override
109 | protected void onScrollChanged(int l, int t, int oldl, int oldt) {
110 | View view=(View)getChildAt(getChildCount() - 1);
111 | int diff=(view.getBottom() - (getHeight() + getScrollY()));// Calculate the scrolldiff
112 | if(diff == 0) { // if diff is zero, then the bottom has been reached
113 | // Log.d("scrollview", "MyScrollView: Bottom has been reached");
114 | if(mOnReachBottomListener != null) {
115 | mOnReachBottomListener.onReachBotton();
116 | }
117 | } else {
118 | if(mOnReachBottomListener != null) {
119 | mOnReachBottomListener.onLeaveBottton();
120 | }
121 | }
122 | super.onScrollChanged(l, t, oldl, oldt);
123 | }
124 |
125 | }
126 |
127 | public interface OnReachBottomListener {
128 |
129 | void onReachBotton();
130 |
131 | void onLeaveBottton();
132 | }
133 |
134 | OnReachBottomListener mOnReachBottomListener;
135 |
136 | public void setOnReachBottomListener(OnReachBottomListener mOnReachBottomListener) {
137 | this.mOnReachBottomListener=mOnReachBottomListener;
138 | }
139 |
140 |
141 | /********************* Custom Listener **************************/
142 | @Override
143 | protected void onScrollChanged(int l, int t, int oldl, int oldt) {
144 | if(getState() == State.OVERSCROLLING) {
145 | setState(State.RESET);
146 | if(scrollView.getOuterScroller() != null) {
147 | scrollView.getOuterScroller().onInnerPullToRefreshScroll(0);
148 | }
149 | }
150 | super.onScrollChanged(l, t, oldl, oldt);
151 | if (this.onScrollChangeListener != null) {
152 | onScrollChangeListener.onScrollChanged(l, t, oldl, oldt);
153 | }
154 | if(t<=0 && oldt <=0) {
155 | informOuterScrollerThatImScrolling(t);
156 | }
157 | }
158 |
159 | private void informOuterScrollerThatImScrolling(int t) {
160 | if(scrollView != null && scrollView.getOuterScroller()!=null) {
161 | scrollView.getOuterScroller().onInnerPullToRefreshScroll(t);
162 | }
163 | }
164 |
165 | private OnScrollChangeListener onScrollChangeListener;
166 |
167 | private void setOnScrollChangeListener(OnScrollChangeListener listener) {
168 | this.onScrollChangeListener = listener;
169 | }
170 |
171 | public interface OnScrollChangeListener {
172 | void onScrollChanged(int l, int t, int oldl, int oldt);
173 | }
174 |
175 | }
176 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/java/com/culiu/mhvp/integrated/ptr/pulltorefresh/ILoadingLayout.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.integrated.ptr.pulltorefresh;
2 |
3 | import android.graphics.Typeface;
4 | import android.graphics.drawable.Drawable;
5 |
6 | public interface ILoadingLayout {
7 |
8 | /**
9 | * Set the Last Updated Text. This displayed under the main label when Pulling
10 | * @param label - Label to set
11 | */
12 | public void setLastUpdatedLabel(CharSequence label);
13 |
14 | /**
15 | * Set the drawable used in the loading layout. This is the same as calling setLoadingDrawable(drawable, Mode.BOTH)
16 | * @param drawable - Drawable to display
17 | */
18 | public void setLoadingDrawable(Drawable drawable);
19 |
20 | /**
21 | * Set Text to show when the Widget is being Pulled setPullLabel(releaseLabel, Mode.BOTH)
22 | * @param pullLabel - CharSequence to display
23 | */
24 | public void setPullLabel(CharSequence pullLabel);
25 |
26 | /**
27 | * Set Text to show when the Widget is refreshing setRefreshingLabel(releaseLabel, Mode.BOTH)
28 | * @param refreshingLabel - CharSequence to display
29 | */
30 | public void setRefreshingLabel(CharSequence refreshingLabel);
31 |
32 | /**
33 | * Set Text to show when the Widget is being pulled, and will refresh when released. This is the same as calling
34 | * setReleaseLabel(releaseLabel, Mode.BOTH)
35 | * @param releaseLabel - CharSequence to display
36 | */
37 | public void setReleaseLabel(CharSequence releaseLabel);
38 |
39 | /**
40 | * Set's the Sets the typeface and style in which the text should be displayed. Please see
41 | * {@link android.widget.TextView#setTypeface(Typeface) TextView#setTypeface(Typeface)}.
42 | */
43 | public void setTextTypeface(Typeface tf);
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/java/com/culiu/mhvp/integrated/ptr/pulltorefresh/IPullToRefresh.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3 | * except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
4 | * required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing
6 | * permissions and limitations under the License.
7 | *******************************************************************************/
8 | package com.culiu.mhvp.integrated.ptr.pulltorefresh;
9 |
10 | import android.view.View;
11 | import android.view.animation.Interpolator;
12 |
13 | public interface IPullToRefresh {
14 |
15 | /**
16 | * Demos the Pull-to-Refresh functionality to the user so that they are aware it is there. This could be useful when the user
17 | * first opens your app, etc. The animation will only happen if the Refresh View (ListView, ScrollView, etc) is in a state where
18 | * a Pull-to-Refresh could occur by a user's touch gesture (i.e. scrolled to the top/bottom).
19 | * @return true - if the Demo has been started, false if not.
20 | */
21 | public boolean demo();
22 |
23 | /**
24 | * Get the mode that this view is currently in. This is only really useful when using Mode.BOTH
.
25 | * @return Mode that the view is currently in
26 | */
27 | public PullToRefreshBase.Mode getCurrentMode();
28 |
29 | /**
30 | * Returns whether the Touch Events are filtered or not. If true is returned, then the View will only use touch events where the
31 | * difference in the Y-axis is greater than the difference in the X-axis. This means that the View will not interfere when it is
32 | * used in a horizontal scrolling View (such as a ViewPager).
33 | * @return boolean - true if the View is filtering Touch Events
34 | */
35 | public boolean getFilterTouchEvents();
36 |
37 | /**
38 | * Returns a proxy object which allows you to call methods on all of the LoadingLayouts (the Views which show when
39 | * Pulling/Refreshing).
40 | *
41 | * You should not keep the result of this method any longer than you need it.
42 | * @return Object which will proxy any calls you make on it, to all of the LoadingLayouts.
43 | */
44 | public ILoadingLayout getLoadingLayoutProxy();
45 |
46 | /**
47 | * Returns a proxy object which allows you to call methods on the LoadingLayouts (the Views which show when Pulling/Refreshing).
48 | * The actual LoadingLayout(s) which will be affected, are chosen by the parameters you give.
49 | *
50 | * You should not keep the result of this method any longer than you need it.
51 | * @param includeStart - Whether to include the Start/Header Views
52 | * @param includeEnd - Whether to include the End/Footer Views
53 | * @return Object which will proxy any calls you make on it, to the LoadingLayouts included.
54 | */
55 | public ILoadingLayout getLoadingLayoutProxy(boolean includeStart, boolean includeEnd);
56 |
57 | /**
58 | * Get the mode that this view has been set to. If this returns Mode.BOTH
, you can use
59 | * getCurrentMode()
to check which mode the view is currently in
60 | * @return Mode that the view has been set to
61 | */
62 | public PullToRefreshBase.Mode getMode();
63 |
64 | /**
65 | * Get the Wrapped Refreshable View. Anything returned here has already been added to the content view.
66 | * @return The View which is currently wrapped
67 | */
68 | public T getRefreshableView();
69 |
70 | /**
71 | * Get whether the 'Refreshing' View should be automatically shown when refreshing. Returns true by default.
72 | * @return - true if the Refreshing View will be show
73 | */
74 | public boolean getShowViewWhileRefreshing();
75 |
76 | /**
77 | * @return - The state that the View is currently in.
78 | */
79 | public PullToRefreshBase.State getState();
80 |
81 | /**
82 | * Whether Pull-to-Refresh is enabled
83 | * @return enabled
84 | */
85 | public boolean isPullToRefreshEnabled();
86 |
87 | /**
88 | * Gets whether Overscroll support is enabled. This is different to Android's standard Overscroll support (the edge-glow) which
89 | * is available from GINGERBREAD onwards
90 | * @return true - if both PullToRefresh-OverScroll and Android's inbuilt OverScroll are enabled
91 | */
92 | public boolean isPullToRefreshOverScrollEnabled();
93 |
94 | /**
95 | * Returns whether the Widget is currently in the Refreshing mState
96 | * @return true if the Widget is currently refreshing
97 | */
98 | public boolean isRefreshing();
99 |
100 | /**
101 | * Returns whether the widget has enabled scrolling on the Refreshable View while refreshing.
102 | * @return true if the widget has enabled scrolling while refreshing
103 | */
104 | public boolean isScrollingWhileRefreshingEnabled();
105 |
106 | /**
107 | * Mark the current Refresh as complete. Will Reset the UI and hide the Refreshing View
108 | */
109 | public void onRefreshComplete();
110 |
111 | /**
112 | * Set the Touch Events to be filtered or not. If set to true, then the View will only use touch events where the difference in
113 | * the Y-axis is greater than the difference in the X-axis. This means that the View will not interfere when it is used in a
114 | * horizontal scrolling View (such as a ViewPager), but will restrict which types of finger scrolls will trigger the View.
115 | * @param filterEvents - true if you want to filter Touch Events. Default is true.
116 | */
117 | public void setFilterTouchEvents(boolean filterEvents);
118 |
119 | /**
120 | * Set the mode of Pull-to-Refresh that this view will use.
121 | * @param mode - Mode to set the View to
122 | */
123 | public void setMode(PullToRefreshBase.Mode mode);
124 |
125 | /**
126 | * Set OnPullEventListener for the Widget
127 | * @param listener - Listener to be used when the Widget has a pull event to propogate.
128 | */
129 | public void setOnPullEventListener(PullToRefreshBase.OnPullEventListener listener);
130 |
131 | /**
132 | * Set OnRefreshListener for the Widget
133 | * @param listener - Listener to be used when the Widget is set to Refresh
134 | */
135 | public void setOnRefreshListener(PullToRefreshBase.OnRefreshListener listener);
136 |
137 | /**
138 | * Set OnRefreshListener for the Widget
139 | * @param listener - Listener to be used when the Widget is set to Refresh
140 | */
141 | public void setOnRefreshListener(PullToRefreshBase.OnRefreshListener2 listener);
142 |
143 | /**
144 | * Sets whether Overscroll support is enabled. This is different to Android's standard Overscroll support (the edge-glow). This
145 | * setting only takes effect when running on device with Android v2.3 or greater.
146 | * @param enabled - true if you want Overscroll enabled
147 | */
148 | public void setPullToRefreshOverScrollEnabled(boolean enabled);
149 |
150 | /**
151 | * Sets the Widget to be in the refresh state. The UI will be updated to show the 'Refreshing' view, and be scrolled to show
152 | * such.
153 | */
154 | public void setRefreshing();
155 |
156 | /**
157 | * Sets the Widget to be in the refresh state. The UI will be updated to show the 'Refreshing' view.
158 | * @param doScroll - true if you want to force a scroll to the Refreshing view.
159 | */
160 | public void setRefreshing(boolean doScroll);
161 |
162 | /**
163 | * Sets the Animation Interpolator that is used for animated scrolling. Defaults to a DecelerateInterpolator
164 | * @param interpolator - Interpolator to use
165 | */
166 | public void setScrollAnimationInterpolator(Interpolator interpolator);
167 |
168 | /**
169 | * By default the Widget disables scrolling on the Refreshable View while refreshing. This method can change this behaviour.
170 | * @param scrollingWhileRefreshingEnabled - true if you want to enable scrolling while refreshing
171 | */
172 | public void setScrollingWhileRefreshingEnabled(boolean scrollingWhileRefreshingEnabled);
173 |
174 | /**
175 | * A mutator to enable/disable whether the 'Refreshing' View should be automatically shown when refreshing.
176 | * @param showView
177 | */
178 | public void setShowViewWhileRefreshing(boolean showView);
179 |
180 | }
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/java/com/culiu/mhvp/integrated/ptr/pulltorefresh/LoadingLayoutProxy.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.integrated.ptr.pulltorefresh;
2 |
3 | import android.graphics.Typeface;
4 | import android.graphics.drawable.Drawable;
5 |
6 | import com.culiu.mhvp.integrated.ptr.pulltorefresh.internal.LoadingLayout;
7 |
8 | import java.util.HashSet;
9 |
10 | public class LoadingLayoutProxy implements ILoadingLayout {
11 |
12 | private final HashSet mLoadingLayouts;
13 |
14 | LoadingLayoutProxy() {
15 | mLoadingLayouts=new HashSet();
16 | }
17 |
18 | /**
19 | * This allows you to add extra LoadingLayout instances to this proxy. This is only necessary if you keep your own instances,
20 | * and want to have them included in any {@link PullToRefreshBase#createLoadingLayoutProxy(boolean, boolean)
21 | * createLoadingLayoutProxy(...)} calls.
22 | * @param layout - LoadingLayout to have included.
23 | */
24 | public void addLayout(LoadingLayout layout) {
25 | if(null != layout) {
26 | mLoadingLayouts.add(layout);
27 | }
28 | }
29 |
30 | @Override
31 | public void setLastUpdatedLabel(CharSequence label) {
32 | for(LoadingLayout layout: mLoadingLayouts) {
33 | layout.setLastUpdatedLabel(label);
34 | }
35 | }
36 |
37 | @Override
38 | public void setLoadingDrawable(Drawable drawable) {
39 | for(LoadingLayout layout: mLoadingLayouts) {
40 | layout.setLoadingDrawable(drawable);
41 | }
42 | }
43 |
44 | @Override
45 | public void setRefreshingLabel(CharSequence refreshingLabel) {
46 | for(LoadingLayout layout: mLoadingLayouts) {
47 | layout.setRefreshingLabel(refreshingLabel);
48 | }
49 | }
50 |
51 | @Override
52 | public void setPullLabel(CharSequence label) {
53 | for(LoadingLayout layout: mLoadingLayouts) {
54 | layout.setPullLabel(label);
55 | }
56 | }
57 |
58 | @Override
59 | public void setReleaseLabel(CharSequence label) {
60 | for(LoadingLayout layout: mLoadingLayouts) {
61 | layout.setReleaseLabel(label);
62 | }
63 | }
64 |
65 | public void setTextTypeface(Typeface tf) {
66 | for(LoadingLayout layout: mLoadingLayouts) {
67 | layout.setTextTypeface(tf);
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/java/com/culiu/mhvp/integrated/ptr/pulltorefresh/OverscrollHelper.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3 | * except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
4 | * required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing
6 | * permissions and limitations under the License.
7 | *******************************************************************************/
8 | package com.culiu.mhvp.integrated.ptr.pulltorefresh;
9 |
10 | import android.annotation.TargetApi;
11 | import android.view.View;
12 |
13 | @TargetApi(9)
14 | public final class OverscrollHelper {
15 |
16 | static final String LOG_TAG="OverscrollHelper";
17 |
18 | static final float DEFAULT_OVERSCROLL_SCALE=1f;
19 |
20 | /**
21 | * Helper method for Overscrolling that encapsulates all of the necessary function.
22 | *
23 | * This should only be used on AdapterView's such as ListView as it just calls through to overScrollBy() with the scrollRange =
24 | * 0. AdapterView's do not have a scroll range (i.e. getListViewScrollY() doesn't work).
25 | * @param view - PullToRefreshView that is calling this.
26 | * @param deltaX - Change in X in pixels, passed through from from overScrollBy call
27 | * @param scrollX - Current X scroll value in pixels before applying deltaY, passed through from from overScrollBy call
28 | * @param deltaY - Change in Y in pixels, passed through from from overScrollBy call
29 | * @param scrollY - Current Y scroll value in pixels before applying deltaY, passed through from from overScrollBy call
30 | * @param isTouchEvent - true if this scroll operation is the result of a touch event, passed through from from overScrollBy
31 | * call
32 | */
33 | public static void overScrollBy(final PullToRefreshBase> view, final int deltaX, final int scrollX, final int deltaY,
34 | final int scrollY, final boolean isTouchEvent) {
35 | overScrollBy(view, deltaX, scrollX, deltaY, scrollY, 0, isTouchEvent);
36 | }
37 |
38 | /**
39 | * Helper method for Overscrolling that encapsulates all of the necessary function. This version of the call is used for Views
40 | * that need to specify a Scroll Range but scroll back to it's edge correctly.
41 | * @param view - PullToRefreshView that is calling this.
42 | * @param deltaX - Change in X in pixels, passed through from from overScrollBy call
43 | * @param scrollX - Current X scroll value in pixels before applying deltaY, passed through from from overScrollBy call
44 | * @param deltaY - Change in Y in pixels, passed through from from overScrollBy call
45 | * @param scrollY - Current Y scroll value in pixels before applying deltaY, passed through from from overScrollBy call
46 | * @param scrollRange - Scroll Range of the View, specifically needed for ScrollView
47 | * @param isTouchEvent - true if this scroll operation is the result of a touch event, passed through from from overScrollBy
48 | * call
49 | */
50 | public static void overScrollBy(final PullToRefreshBase> view, final int deltaX, final int scrollX, final int deltaY,
51 | final int scrollY, final int scrollRange, final boolean isTouchEvent) {
52 | overScrollBy(view, deltaX, scrollX, deltaY, scrollY, scrollRange, 0, DEFAULT_OVERSCROLL_SCALE, isTouchEvent);
53 | }
54 |
55 | /**
56 | * Helper method for Overscrolling that encapsulates all of the necessary function. This is the advanced version of the call.
57 | * @param view - PullToRefreshView that is calling this.
58 | * @param deltaX - Change in X in pixels, passed through from from overScrollBy call
59 | * @param scrollX - Current X scroll value in pixels before applying deltaY, passed through from from overScrollBy call
60 | * @param deltaY - Change in Y in pixels, passed through from from overScrollBy call
61 | * @param scrollY - Current Y scroll value in pixels before applying deltaY, passed through from from overScrollBy call
62 | * @param scrollRange - Scroll Range of the View, specifically needed for ScrollView
63 | * @param fuzzyThreshold - Threshold for which the values how fuzzy we should treat the other values. Needed for WebView as it
64 | * doesn't always scroll back to it's edge. 0 = no fuzziness.
65 | * @param scaleFactor - Scale Factor for overscroll amount
66 | * @param isTouchEvent - true if this scroll operation is the result of a touch event, passed through from from overScrollBy
67 | * call
68 | */
69 | public static void overScrollBy(final PullToRefreshBase> view, final int deltaX, final int scrollX, final int deltaY,
70 | final int scrollY, final int scrollRange, final int fuzzyThreshold, final float scaleFactor, final boolean isTouchEvent) {
71 |
72 | final int deltaValue, currentScrollValue, scrollValue;
73 | switch(view.getPullToRefreshScrollDirection()) {
74 | case HORIZONTAL:
75 | deltaValue=deltaX;
76 | scrollValue=scrollX;
77 | currentScrollValue=view.getScrollX();
78 | break;
79 | case VERTICAL:
80 | default:
81 | deltaValue=deltaY;
82 | scrollValue=scrollY;
83 | currentScrollValue=view.getScrollY();
84 | break;
85 | }
86 |
87 | // Check that OverScroll is enabled and that we're not currently
88 | // refreshing.
89 | if(view.isPullToRefreshOverScrollEnabled() && !view.isRefreshing()) {
90 | final PullToRefreshBase.Mode mode=view.getMode();
91 |
92 | // Check that Pull-to-Refresh is enabled, and the event isn't from
93 | // touch
94 | if(mode.permitsPullToRefresh() && !isTouchEvent && deltaValue != 0) {
95 | final int newScrollValue=(deltaValue + scrollValue);
96 |
97 | if(newScrollValue < (0 - fuzzyThreshold)) {
98 | // Check the mode supports the overscroll direction, and
99 | // then move scroll
100 | if(mode.showHeaderLoadingLayout()) {
101 | // If we're currently at zero, we're about to start
102 | // overscrolling, so change the state
103 | if(currentScrollValue == 0) {
104 | view.setState(PullToRefreshBase.State.OVERSCROLLING);
105 | }
106 |
107 | view.setHeaderScroll((int)(scaleFactor * (currentScrollValue + newScrollValue)));
108 | }
109 | } else if(newScrollValue > (scrollRange + fuzzyThreshold)) {
110 | // Check the mode supports the overscroll direction, and
111 | // then move scroll
112 | if(mode.showFooterLoadingLayout()) {
113 | // If we're currently at zero, we're about to start
114 | // overscrolling, so change the state
115 | if(currentScrollValue == 0) {
116 | view.setState(PullToRefreshBase.State.OVERSCROLLING);
117 | }
118 |
119 | view.setHeaderScroll((int)(scaleFactor * (currentScrollValue + newScrollValue - scrollRange)));
120 | }
121 | } else if(Math.abs(newScrollValue) <= fuzzyThreshold || Math.abs(newScrollValue - scrollRange) <= fuzzyThreshold) {
122 | // Means we've stopped overscrolling, so scroll back to 0
123 | view.setState(PullToRefreshBase.State.RESET);
124 | }
125 | } else if(isTouchEvent && PullToRefreshBase.State.OVERSCROLLING == view.getState()) {
126 | // This condition means that we were overscrolling from a fling,
127 | // but the user has touched the View and is now overscrolling
128 | // from touch instead. We need to just reset.
129 | view.setState(PullToRefreshBase.State.RESET);
130 | }
131 | }
132 | }
133 |
134 | static boolean isAndroidOverScrollEnabled(View view) {
135 | return view.getOverScrollMode() != View.OVER_SCROLL_NEVER;
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/java/com/culiu/mhvp/integrated/ptr/pulltorefresh/internal/EmptyViewMethodAccessor.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3 | * except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
4 | * required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing
6 | * permissions and limitations under the License.
7 | *******************************************************************************/
8 | package com.culiu.mhvp.integrated.ptr.pulltorefresh.internal;
9 |
10 | import android.view.View;
11 |
12 | /**
13 | * Interface that allows PullToRefreshBase to hijack the call to AdapterView.setEmptyView()
14 | * @author chris
15 | */
16 | public interface EmptyViewMethodAccessor {
17 |
18 | /**
19 | * Calls upto AdapterView.setEmptyView()
20 | * @param emptyView - to set as Empty View
21 | */
22 | public void setEmptyViewInternal(View emptyView);
23 |
24 | /**
25 | * Should call PullToRefreshBase.setEmptyView() which will then automatically call through to setEmptyViewInternal()
26 | * @param emptyView - to set as Empty View
27 | */
28 | public void setEmptyView(View emptyView);
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/java/com/culiu/mhvp/integrated/ptr/pulltorefresh/internal/FlipLoadingLayout.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3 | * except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
4 | * required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing
6 | * permissions and limitations under the License.
7 | *******************************************************************************/
8 | package com.culiu.mhvp.integrated.ptr.pulltorefresh.internal;
9 |
10 | import android.annotation.SuppressLint;
11 | import android.content.Context;
12 | import android.content.res.TypedArray;
13 | import android.graphics.Matrix;
14 | import android.graphics.drawable.Drawable;
15 | import android.view.View;
16 | import android.view.ViewGroup;
17 | import android.view.animation.Animation;
18 | import android.view.animation.RotateAnimation;
19 | import android.widget.ImageView.ScaleType;
20 |
21 | import com.culiu.mhvp.integrated.ptr.pulltorefresh.PullToRefreshBase;
22 | import com.culiu.mhvp.integrated.ptr.R;
23 |
24 | @SuppressLint("ViewConstructor")
25 | public class FlipLoadingLayout extends LoadingLayout {
26 |
27 | static final int FLIP_ANIMATION_DURATION=150;
28 |
29 | private final Animation mRotateAnimation, mResetRotateAnimation;
30 |
31 | public FlipLoadingLayout(Context context, final PullToRefreshBase.Mode mode, final PullToRefreshBase.Orientation scrollDirection, TypedArray attrs, int layoutId) {
32 | super(context, mode, scrollDirection, attrs, layoutId);
33 |
34 | final int rotateAngle=mode == PullToRefreshBase.Mode.PULL_FROM_START ? -180 : 180;
35 |
36 | mRotateAnimation=new RotateAnimation(0, rotateAngle, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
37 | mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR);
38 | mRotateAnimation.setDuration(FLIP_ANIMATION_DURATION);
39 | mRotateAnimation.setFillAfter(true);
40 |
41 | mResetRotateAnimation=
42 | new RotateAnimation(rotateAngle, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
43 | mResetRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR);
44 | mResetRotateAnimation.setDuration(FLIP_ANIMATION_DURATION);
45 | mResetRotateAnimation.setFillAfter(true);
46 | }
47 |
48 | @Override
49 | protected void onLoadingDrawableSet(Drawable imageDrawable) {
50 | if(null != imageDrawable) {
51 | final int dHeight=imageDrawable.getIntrinsicHeight();
52 | final int dWidth=imageDrawable.getIntrinsicWidth();
53 |
54 | /**
55 | * We need to set the width/height of the ImageView so that it is square with each side the size of the largest drawable
56 | * dimension. This is so that it doesn't clip when rotated.
57 | */
58 | ViewGroup.LayoutParams lp=mHeaderImage.getLayoutParams();
59 | lp.width=lp.height=Math.max(dHeight, dWidth);
60 | mHeaderImage.requestLayout();
61 |
62 | /**
63 | * We now rotate the Drawable so that is at the correct rotation, and is centered.
64 | */
65 | mHeaderImage.setScaleType(ScaleType.MATRIX);
66 | Matrix matrix=new Matrix();
67 | matrix.postTranslate((lp.width - dWidth) / 2f, (lp.height - dHeight) / 2f);
68 | matrix.postRotate(getDrawableRotationAngle(), lp.width / 2f, lp.height / 2f);
69 | mHeaderImage.setImageMatrix(matrix);
70 | }
71 | }
72 |
73 | @Override
74 | protected void onPullImpl(float scaleOfLayout) {
75 | // NO-OP
76 | }
77 |
78 | @Override
79 | protected void pullToRefreshImpl() {
80 | // Only start reset Animation, we've previously show the rotate anim
81 | if(mRotateAnimation == mHeaderImage.getAnimation()) {
82 | mHeaderImage.startAnimation(mResetRotateAnimation);
83 | }
84 | }
85 |
86 | @Override
87 | protected void refreshingImpl() {
88 | mHeaderImage.clearAnimation();
89 | mHeaderImage.setVisibility(View.INVISIBLE);
90 | mHeaderProgress.setVisibility(View.VISIBLE);
91 | }
92 |
93 | @Override
94 | protected void releaseToRefreshImpl() {
95 | mHeaderImage.startAnimation(mRotateAnimation);
96 | }
97 |
98 | @Override
99 | protected void resetImpl() {
100 | mHeaderImage.clearAnimation();
101 | mHeaderProgress.setVisibility(View.GONE);
102 | mHeaderImage.setVisibility(View.VISIBLE);
103 | }
104 |
105 | @Override
106 | protected int getDefaultDrawableResId() {
107 | return R.drawable.default_ptr_flip;
108 | }
109 |
110 | private float getDrawableRotationAngle() {
111 | float angle=0f;
112 | switch(mMode) {
113 | case PULL_FROM_END:
114 | if(mScrollDirection == PullToRefreshBase.Orientation.HORIZONTAL) {
115 | angle=90f;
116 | } else {
117 | angle=180f;
118 | }
119 | break;
120 |
121 | case PULL_FROM_START:
122 | if(mScrollDirection == PullToRefreshBase.Orientation.HORIZONTAL) {
123 | angle=270f;
124 | }
125 | break;
126 |
127 | default:
128 | break;
129 | }
130 |
131 | return angle;
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/java/com/culiu/mhvp/integrated/ptr/pulltorefresh/internal/IndicatorLayout.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3 | * except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
4 | * required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing
6 | * permissions and limitations under the License.
7 | *******************************************************************************/
8 | package com.culiu.mhvp.integrated.ptr.pulltorefresh.internal;
9 |
10 | import android.annotation.SuppressLint;
11 | import android.content.Context;
12 | import android.graphics.Color;
13 | import android.graphics.Matrix;
14 | import android.graphics.drawable.ColorDrawable;
15 | import android.graphics.drawable.Drawable;
16 | import android.view.View;
17 | import android.view.animation.Animation;
18 | import android.view.animation.Animation.AnimationListener;
19 | import android.view.animation.AnimationUtils;
20 | import android.view.animation.Interpolator;
21 | import android.view.animation.LinearInterpolator;
22 | import android.view.animation.RotateAnimation;
23 | import android.widget.FrameLayout;
24 | import android.widget.ImageView;
25 | import android.widget.ImageView.ScaleType;
26 |
27 | import com.culiu.mhvp.integrated.ptr.pulltorefresh.PullToRefreshBase;
28 | import com.culiu.mhvp.integrated.ptr.R;
29 |
30 | @SuppressLint("ViewConstructor")
31 | public class IndicatorLayout extends FrameLayout implements AnimationListener {
32 |
33 | static final int DEFAULT_ROTATION_ANIMATION_DURATION=150;
34 |
35 | private Animation mInAnim, mOutAnim;
36 |
37 | private ImageView mArrowImageView;
38 |
39 | private final Animation mRotateAnimation, mResetRotateAnimation;
40 |
41 | public IndicatorLayout(Context context, PullToRefreshBase.Mode mode) {
42 | super(context);
43 | mArrowImageView=new ImageView(context);
44 |
45 | // Drawable arrowD=getResources().getDrawable(R.drawable.indicator_arrow);
46 | Drawable arrowD=new ColorDrawable(Color.TRANSPARENT);
47 | mArrowImageView.setImageDrawable(arrowD);
48 |
49 | final int padding=getResources().getDimensionPixelSize(R.dimen.indicator_internal_padding);
50 | mArrowImageView.setPadding(padding, padding, padding, padding);
51 | addView(mArrowImageView);
52 |
53 | int inAnimResId, outAnimResId;
54 | switch(mode) {
55 | case PULL_FROM_END:
56 | inAnimResId=R.anim.slide_in_from_bottom;
57 | outAnimResId=R.anim.slide_out_to_bottom;
58 | setBackgroundResource(R.drawable.indicator_bg_bottom);
59 |
60 | // Rotate Arrow so it's pointing the correct way
61 | mArrowImageView.setScaleType(ScaleType.MATRIX);
62 | Matrix matrix=new Matrix();
63 | matrix.setRotate(180f, arrowD.getIntrinsicWidth() / 2f, arrowD.getIntrinsicHeight() / 2f);
64 | mArrowImageView.setImageMatrix(matrix);
65 | break;
66 | default:
67 | case PULL_FROM_START:
68 | inAnimResId=R.anim.slide_in_from_top;
69 | outAnimResId=R.anim.slide_out_to_top;
70 | setBackgroundResource(R.drawable.indicator_bg_top);
71 | break;
72 | }
73 |
74 | mInAnim=AnimationUtils.loadAnimation(context, inAnimResId);
75 | mInAnim.setAnimationListener(this);
76 |
77 | mOutAnim=AnimationUtils.loadAnimation(context, outAnimResId);
78 | mOutAnim.setAnimationListener(this);
79 |
80 | final Interpolator interpolator=new LinearInterpolator();
81 | mRotateAnimation=new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
82 | mRotateAnimation.setInterpolator(interpolator);
83 | mRotateAnimation.setDuration(DEFAULT_ROTATION_ANIMATION_DURATION);
84 | mRotateAnimation.setFillAfter(true);
85 |
86 | mResetRotateAnimation=new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
87 | mResetRotateAnimation.setInterpolator(interpolator);
88 | mResetRotateAnimation.setDuration(DEFAULT_ROTATION_ANIMATION_DURATION);
89 | mResetRotateAnimation.setFillAfter(true);
90 |
91 | }
92 |
93 | public final boolean isVisible() {
94 | Animation currentAnim=getAnimation();
95 | if(null != currentAnim) {
96 | return mInAnim == currentAnim;
97 | }
98 |
99 | return getVisibility() == View.VISIBLE;
100 | }
101 |
102 | public void hide() {
103 | startAnimation(mOutAnim);
104 | }
105 |
106 | public void show() {
107 | mArrowImageView.clearAnimation();
108 | startAnimation(mInAnim);
109 | }
110 |
111 | @Override
112 | public void onAnimationEnd(Animation animation) {
113 | if(animation == mOutAnim) {
114 | mArrowImageView.clearAnimation();
115 | setVisibility(View.GONE);
116 | } else if(animation == mInAnim) {
117 | setVisibility(View.VISIBLE);
118 | }
119 |
120 | clearAnimation();
121 | }
122 |
123 | @Override
124 | public void onAnimationRepeat(Animation animation) {
125 | // NO-OP
126 | }
127 |
128 | @Override
129 | public void onAnimationStart(Animation animation) {
130 | setVisibility(View.VISIBLE);
131 | }
132 |
133 | public void releaseToRefresh() {
134 | mArrowImageView.startAnimation(mRotateAnimation);
135 | }
136 |
137 | public void pullToRefresh() {
138 | mArrowImageView.startAnimation(mResetRotateAnimation);
139 | }
140 |
141 | }
142 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/java/com/culiu/mhvp/integrated/ptr/pulltorefresh/internal/RotateLoadingLayout.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3 | * except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
4 | * required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing
6 | * permissions and limitations under the License.
7 | *******************************************************************************/
8 | package com.culiu.mhvp.integrated.ptr.pulltorefresh.internal;
9 |
10 | import android.content.Context;
11 | import android.content.res.TypedArray;
12 | import android.graphics.Matrix;
13 | import android.graphics.drawable.Drawable;
14 | import android.view.animation.Animation;
15 | import android.view.animation.RotateAnimation;
16 | import android.widget.ImageView.ScaleType;
17 |
18 | import com.culiu.mhvp.integrated.ptr.pulltorefresh.PullToRefreshBase;
19 | import com.culiu.mhvp.integrated.ptr.R;
20 |
21 | public class RotateLoadingLayout extends LoadingLayout {
22 |
23 | static final int ROTATION_ANIMATION_DURATION=1200;
24 |
25 | private final Animation mRotateAnimation;
26 |
27 | private final Matrix mHeaderImageMatrix;
28 |
29 | private float mRotationPivotX, mRotationPivotY;
30 |
31 | private final boolean mRotateDrawableWhilePulling;
32 |
33 | public RotateLoadingLayout(Context context, PullToRefreshBase.Mode mode, PullToRefreshBase.Orientation scrollDirection, TypedArray attrs, int layoutId) {
34 | super(context, mode, scrollDirection, attrs, layoutId);
35 |
36 | mRotateDrawableWhilePulling=attrs.getBoolean(R.styleable.PullToRefresh_ptrRotateDrawableWhilePulling, true);
37 |
38 | mHeaderImage.setScaleType(ScaleType.MATRIX);
39 | mHeaderImageMatrix=new Matrix();
40 | mHeaderImage.setImageMatrix(mHeaderImageMatrix);
41 |
42 | mRotateAnimation=new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
43 | mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR);
44 | mRotateAnimation.setDuration(ROTATION_ANIMATION_DURATION);
45 | mRotateAnimation.setRepeatCount(Animation.INFINITE);
46 | mRotateAnimation.setRepeatMode(Animation.RESTART);
47 | }
48 |
49 | public void onLoadingDrawableSet(Drawable imageDrawable) {
50 | if(null != imageDrawable) {
51 | mRotationPivotX=Math.round(imageDrawable.getIntrinsicWidth() / 2f);
52 | mRotationPivotY=Math.round(imageDrawable.getIntrinsicHeight() / 2f);
53 | }
54 | }
55 |
56 | protected void onPullImpl(float scaleOfLayout) {
57 | float angle;
58 | if(mRotateDrawableWhilePulling) {
59 | angle=scaleOfLayout * 90f;
60 | } else {
61 | angle=Math.max(0f, Math.min(180f, scaleOfLayout * 360f - 180f));
62 | }
63 |
64 | mHeaderImageMatrix.setRotate(angle, mRotationPivotX, mRotationPivotY);
65 | mHeaderImage.setImageMatrix(mHeaderImageMatrix);
66 | }
67 |
68 | @Override
69 | protected void refreshingImpl() {
70 | mHeaderImage.startAnimation(mRotateAnimation);
71 | }
72 |
73 | @Override
74 | protected void resetImpl() {
75 | mHeaderImage.clearAnimation();
76 | resetImageRotation();
77 | }
78 |
79 | private void resetImageRotation() {
80 | if(null != mHeaderImageMatrix) {
81 | mHeaderImageMatrix.reset();
82 | mHeaderImage.setImageMatrix(mHeaderImageMatrix);
83 | }
84 | }
85 |
86 | @Override
87 | protected void pullToRefreshImpl() {
88 | // NO-OP
89 | }
90 |
91 | @Override
92 | protected void releaseToRefreshImpl() {
93 | // NO-OP
94 | }
95 |
96 | @Override
97 | protected int getDefaultDrawableResId() {
98 | return R.drawable.default_ptr_rotate;
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/java/com/culiu/mhvp/integrated/ptr/pulltorefresh/internal/Utils.java:
--------------------------------------------------------------------------------
1 | package com.culiu.mhvp.integrated.ptr.pulltorefresh.internal;
2 |
3 | public class Utils {
4 |
5 | static final String LOG_TAG="PullToRefresh";
6 |
7 | public static void warnDeprecation(String depreacted, String replacement) {
8 | // Log.w(LOG_TAG, "You're using the deprecated " + depreacted + " attr, please switch over to " + replacement);
9 | }
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/java/com/culiu/mhvp/integrated/ptr/pulltorefresh/internal/ViewCompat.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
3 | * except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless
4 | * required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
5 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing
6 | * permissions and limitations under the License.
7 | *******************************************************************************/
8 | package com.culiu.mhvp.integrated.ptr.pulltorefresh.internal;
9 |
10 | import android.annotation.TargetApi;
11 | import android.graphics.drawable.Drawable;
12 | import android.os.Build.VERSION;
13 | import android.os.Build.VERSION_CODES;
14 | import android.view.View;
15 |
16 | @SuppressWarnings("deprecation")
17 | public class ViewCompat {
18 |
19 | public static void postOnAnimation(View view, Runnable runnable) {
20 | if(VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
21 | SDK16.postOnAnimation(view, runnable);
22 | } else {
23 | view.postDelayed(runnable, 16);
24 | }
25 | }
26 |
27 | public static void setBackground(View view, Drawable background) {
28 | if(VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
29 | SDK16.setBackground(view, background);
30 | } else {
31 | view.setBackgroundDrawable(background);
32 | }
33 | }
34 |
35 | public static void setLayerType(View view, int layerType) {
36 | if(VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
37 | SDK11.setLayerType(view, layerType);
38 | }
39 | }
40 |
41 | @TargetApi(11)
42 | static class SDK11 {
43 |
44 | public static void setLayerType(View view, int layerType) {
45 | view.setLayerType(layerType, null);
46 | }
47 | }
48 |
49 | @TargetApi(16)
50 | static class SDK16 {
51 |
52 | public static void postOnAnimation(View view, Runnable runnable) {
53 | view.postOnAnimation(runnable);
54 | }
55 |
56 | public static void setBackground(View view, Drawable background) {
57 | view.setBackground(background);
58 | }
59 |
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/anim/slide_in_from_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
22 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/anim/slide_in_from_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
22 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/anim/slide_out_to_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
22 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/anim/slide_out_to_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
22 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/drawable-xhdpi/default_ptr_flip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/mhvp-integrated-ptr/src/main/res/drawable-xhdpi/default_ptr_flip.png
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/drawable-xhdpi/default_ptr_rotate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/mhvp-integrated-ptr/src/main/res/drawable-xhdpi/default_ptr_rotate.png
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/drawable/indicator_bg_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
17 |
18 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/drawable/indicator_bg_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
17 |
18 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/layout/default_pull_to_refresh_header_vertical.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
16 |
20 |
21 |
27 |
28 |
36 |
37 |
38 |
44 |
45 |
54 |
55 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 10dp
4 | 12dp
5 | 4dp
6 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/values/ptr_arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/values/ptr_attr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
69 |
70 |
71 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/mhvp-integrated-ptr/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | mhvp-integrated-ptr
3 |
4 |
5 | pull up to refresh…
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/pics/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/pics/1.gif
--------------------------------------------------------------------------------
/pics/2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/pics/2.gif
--------------------------------------------------------------------------------
/pics/3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/pics/3.gif
--------------------------------------------------------------------------------
/pics/4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/pics/4.gif
--------------------------------------------------------------------------------
/pics/5.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/pics/5.gif
--------------------------------------------------------------------------------
/pics/6.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/pics/6.gif
--------------------------------------------------------------------------------
/pics/7.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/pics/7.gif
--------------------------------------------------------------------------------
/pics/8.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/XAVlER-S/MagicHeaderViewPager/790213fbc796e3a8d7ec97b55217e40172ebae54/pics/8.gif
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':demo', ':mhvp-core', ':mhvp-integrated-ptr'
2 |
--------------------------------------------------------------------------------