├── .gitattributes
├── .gitignore
├── .idea
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── inspectionProfiles
│ ├── Project_Default.xml
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── runConfigurations.xml
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── slidbacklib
│ │ ├── App.java
│ │ ├── ListDataActivity.java
│ │ ├── MainActivity.java
│ │ ├── ScrollActivity.java
│ │ ├── WebViewActivity.java
│ │ ├── commonadapter
│ │ ├── ListViewAdapter.java
│ │ ├── RecyclerAdapter.java
│ │ └── viewholders
│ │ │ ├── GodViewHolder.java
│ │ │ ├── RecyclerViewHolder.java
│ │ │ └── ViewHolderImpl.java
│ │ └── utils
│ │ ├── SlideBackLayoutUtils.java
│ │ └── StringUtils.java
│ └── res
│ ├── drawable-xxhdpi
│ ├── icon_title_back.png
│ ├── icon_titlebar_close.png
│ ├── percent_arrow.png
│ └── title_back_icon.png
│ ├── drawable
│ ├── person_item_selector.xml
│ └── webview_progress_style.xml
│ ├── layout
│ ├── activity_list_data.xml
│ ├── activity_main.xml
│ ├── activity_scroll_view.xml
│ ├── activity_web_view.xml
│ └── item_list_data.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── config.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── sideBackLibrary
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
└── main
├── AndroidManifest.xml
├── java
└── com
│ └── slideback
│ ├── ActivityHelper.java
│ ├── SlideBackHelper.java
│ ├── SlideConfig.java
│ ├── callbak
│ ├── OnInternalStateListener.java
│ ├── OnSlideListener.java
│ └── OnSlideListenerAdapter.java
│ └── widget
│ ├── CacheDrawView.java
│ ├── ShadowView.java
│ └── SlideBackLayout.java
└── res
├── anim
├── anim_out_none.xml
├── sback_anim_activity_none.xml
├── sback_close_in.xml
├── sback_close_out.xml
├── sback_open_in.xml
└── sback_open_out.xml
├── drawable
└── sliding_back_shadow.xml
├── layout
└── slide_back_default_layout.xml
└── values
├── strings.xml
└── styles.xml
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | Android > Lint > Usability
39 |
40 |
41 | Code style issuesJava
42 |
43 |
44 | Encapsulation issuesJava
45 |
46 |
47 | Java
48 |
49 |
50 | Naming conventionsJava
51 |
52 |
53 | Resource management issuesJava
54 |
55 |
56 |
57 |
58 | Android
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | 1.8
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | buildToolsVersion "26.0.2"
6 | defaultConfig {
7 | applicationId "com.slidbacklib"
8 | minSdkVersion 14
9 | targetSdkVersion 27
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | testCompile 'junit:junit:4.12'
25 | compile(rootProject.ext.dependencies["appcompat-v7"]) {
26 | exclude module: 'support-v4'
27 | }
28 | compile(rootProject.ext.dependencies["constraint-layout"]) {
29 | exclude module: 'support-annotations'
30 | exclude module: 'appcompat-v7'
31 | exclude module: 'support-v4'
32 | }
33 | compile rootProject.ext.dependencies["recyclerview-v7"]
34 |
35 | // compile rootProject.ext.dependencies["butterknife"]
36 |
37 | //滑动返回
38 | compile project(':sideBackLibrary')
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in E:\android-sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/slidbacklib/App.java:
--------------------------------------------------------------------------------
1 | package com.slidbacklib;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | import com.slideback.ActivityHelper;
7 |
8 | /**
9 | * ===============================
10 | * 描 述:
11 | * 作 者:pjw
12 | * 创建日期:2017/12/26 16:20
13 | * ===============================
14 | */
15 | public class App extends Application {
16 |
17 | private ActivityHelper mActivityHelper;
18 |
19 | //当前app实例对象
20 | public static App sApp;
21 | //全局上下文对象
22 | public static Context sContext;
23 |
24 |
25 | @Override
26 | public void onCreate() {
27 | super.onCreate();
28 | sApp = this;
29 | sContext = this;
30 | getActivityHelper();
31 | }
32 |
33 | public ActivityHelper getActivityHelper() {
34 | if (mActivityHelper == null) {
35 | mActivityHelper = new ActivityHelper();
36 | registerActivityLifecycleCallbacks(mActivityHelper);
37 | }
38 | return mActivityHelper;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/com/slidbacklib/ListDataActivity.java:
--------------------------------------------------------------------------------
1 | package com.slidbacklib;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.support.v7.widget.LinearLayoutManager;
8 | import android.support.v7.widget.RecyclerView;
9 |
10 | import com.slidbacklib.commonadapter.RecyclerAdapter;
11 | import com.slidbacklib.commonadapter.viewholders.RecyclerViewHolder;
12 | import com.slidbacklib.utils.SlideBackLayoutUtils;
13 | import com.slidbacklib.utils.StringUtils;
14 |
15 | /**
16 | * ===============================
17 | * 描 述:
18 | * 作 者:pjw
19 | * 创建日期:2017/12/26 16:01
20 | * ===============================
21 | */
22 | public class ListDataActivity extends AppCompatActivity {
23 |
24 | @Override
25 | protected void onCreate(@Nullable Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | setContentView(R.layout.activity_list_data);
28 | RecyclerView rvRecycler = (RecyclerView) findViewById(R.id.rvRecycler);
29 | rvRecycler.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
30 | RecyclerAdapter adapter = new RecyclerAdapter(R.layout.item_list_data) {
31 | @Override
32 | protected void onBindData(RecyclerViewHolder recyclerViewHolder, int i, String s) {
33 | }
34 | };
35 |
36 | adapter.setOnItemClickListener(new RecyclerAdapter.OnItemClickListener() {
37 | @Override
38 | public void onItemClick(int i) {
39 | startActivity(new Intent(ListDataActivity.this, ScrollActivity.class));
40 | }
41 | });
42 | rvRecycler.setAdapter(adapter);
43 | adapter.clear();
44 | adapter.addItems(StringUtils.getDatas(30));
45 |
46 | SlideBackLayoutUtils.sideBack(this);
47 | }
48 |
49 | @Override
50 | protected void onDestroy() {
51 | SlideBackLayoutUtils.onDestroy(this);
52 | super.onDestroy();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/slidbacklib/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.slidbacklib;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.view.View;
7 |
8 | import com.slidbacklib.utils.SlideBackLayoutUtils;
9 |
10 | public class MainActivity extends AppCompatActivity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_main);
16 |
17 | findViewById(R.id.tvText).setOnClickListener(new View.OnClickListener() {
18 | @Override
19 | public void onClick(View v) {
20 | startActivity(new Intent(MainActivity.this, ListDataActivity.class));
21 | }
22 | });
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/slidbacklib/ScrollActivity.java:
--------------------------------------------------------------------------------
1 | package com.slidbacklib;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.view.View;
8 |
9 | import com.slidbacklib.utils.SlideBackLayoutUtils;
10 |
11 | /**
12 | * ===============================
13 | * 描 述:
14 | * 作 者:pjw
15 | * 创建日期:2017/12/26 16:06
16 | * ===============================
17 | */
18 | public class ScrollActivity extends AppCompatActivity {
19 |
20 | @Override
21 | protected void onCreate(@Nullable Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_scroll_view);
24 | findViewById(R.id.iView).setOnClickListener(new View.OnClickListener() {
25 | @Override
26 | public void onClick(View v) {
27 | // startActivity(new Intent(ScrollActivity.this, MainActivity.class));
28 | startActivity(new Intent(ScrollActivity.this, WebViewActivity.class));
29 | }
30 | });
31 | // findViewById(R.id.iView1).setOnClickListener(new View.OnClickListener() {
32 | // @Override
33 | // public void onClick(View v) {
34 | // startActivity(new Intent(ScrollActivity.this, WebViewActivity.class));
35 | // }
36 | // });
37 | SlideBackLayoutUtils.sideBack(this);
38 | }
39 |
40 |
41 | @Override
42 | protected void onDestroy() {
43 | SlideBackLayoutUtils.onDestroy(this);
44 | super.onDestroy();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/slidbacklib/WebViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.slidbacklib;
2 |
3 | import android.content.Intent;
4 | import android.os.Build;
5 | import android.os.Bundle;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.View;
9 | import android.webkit.WebChromeClient;
10 | import android.webkit.WebSettings;
11 | import android.webkit.WebView;
12 | import android.webkit.WebViewClient;
13 | import android.widget.ProgressBar;
14 | import android.widget.RelativeLayout;
15 | import android.widget.TextView;
16 |
17 | import com.slidbacklib.utils.SlideBackLayoutUtils;
18 |
19 | import static com.slidbacklib.R.id.tv_title_bar_right_text;
20 |
21 | /**
22 | * ===============================
23 | * 描 述:
24 | * 作 者:pjw
25 | * 创建日期:2017/12/26 16:09
26 | * ===============================
27 | */
28 | public class WebViewActivity extends AppCompatActivity {
29 |
30 | TextView tvTitleBarRightText;
31 | WebView cdWebView;
32 | ProgressBar webviewProgressBar;
33 | RelativeLayout cdRootView;
34 |
35 | @Override
36 | protected void onCreate(@Nullable Bundle savedInstanceState) {
37 | super.onCreate(savedInstanceState);
38 | setContentView(R.layout.activity_web_view);
39 |
40 | cdWebView = (WebView) findViewById(R.id.cd_web_view);
41 | tvTitleBarRightText = (TextView) findViewById(R.id.tv_title_bar_right_text);
42 | webviewProgressBar = (ProgressBar) findViewById(R.id.webview_progress_bar);
43 | cdRootView = (RelativeLayout) findViewById(R.id.cd_root_view);
44 | findViewById(R.id.iv_web_title_bar_back).setOnClickListener(new View.OnClickListener() {
45 | @Override
46 | public void onClick(View v) {
47 | finish();
48 | }
49 | });
50 | initData();
51 | SlideBackLayoutUtils.sideBack(this);
52 | }
53 |
54 | private void initData() {
55 | initWebView();
56 | cdWebView.setWebViewClient(mWebViewClient);
57 | cdWebView.setWebChromeClient(mWebChromeClient);
58 | cdWebView.loadUrl("https://www.baidu.com/");
59 |
60 | tvTitleBarRightText.setVisibility(View.VISIBLE);
61 | tvTitleBarRightText.setText("跳转页面");
62 | tvTitleBarRightText.setOnClickListener(new View.OnClickListener() {
63 | @Override
64 | public void onClick(View v) {
65 | startActivity(new Intent(WebViewActivity.this, MainActivity.class));
66 | }
67 | });
68 | }
69 |
70 | private void initWebView() {
71 | WebSettings webSetting = cdWebView.getSettings();
72 | webSetting.setJavaScriptEnabled(true);
73 | webSetting.setJavaScriptCanOpenWindowsAutomatically(true);
74 | webSetting.setAllowUniversalAccessFromFileURLs(true);
75 | webSetting.setAllowFileAccess(true);
76 | webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
77 | webSetting.setSupportZoom(false);
78 | webSetting.setBuiltInZoomControls(true);
79 | webSetting.setUseWideViewPort(true);
80 | webSetting.setSupportMultipleWindows(true);
81 | // webSetting.setLoadWithOverviewMode(true);
82 | webSetting.setAppCacheEnabled(true);
83 | webSetting.setDatabaseEnabled(true);
84 | webSetting.setDomStorageEnabled(true);
85 | // webSetting.setMixedContentMode(android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
86 | webSetting.setGeolocationEnabled(true);
87 | webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
88 | // webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);
89 | webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
90 | // webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
91 | webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);
92 | webSetting.setLoadWithOverviewMode(true);
93 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
94 | webSetting.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
95 | }
96 | }
97 |
98 | /**
99 | * 设置WebChromeClient
100 | * 处理进度条和标题显示
101 | */
102 | private WebChromeClient mWebChromeClient = new WebChromeClient() {
103 | @Override
104 | public void onProgressChanged(WebView webView, int newProgress) {
105 | if (webviewProgressBar != null) {
106 | if (newProgress == 100) {
107 | webviewProgressBar.setProgress(100);
108 | webviewProgressBar.setVisibility(View.GONE);
109 | } else {
110 | if (!webviewProgressBar.isShown()) {
111 | webviewProgressBar.setVisibility(View.VISIBLE);
112 | }
113 | webviewProgressBar.setProgress(newProgress);
114 | }
115 | }
116 | super.onProgressChanged(webView, newProgress);
117 | }
118 |
119 | // public void openFileChooser(ValueCallback filePathCallback) {
120 | // mFilePathCallback = filePathCallback;
121 | // openSelectImageDialog();
122 | // }
123 | //
124 | // public void openFileChooser(ValueCallback filePathCallback, String acceptType) {
125 | // mFilePathCallback = filePathCallback;
126 | // openSelectImageDialog();
127 | // }
128 | //
129 | // public void openFileChooser(ValueCallback filePathCallback, String acceptType, String capture) {
130 | // mFilePathCallback = filePathCallback;
131 | // openSelectImageDialog();
132 | // }
133 | //
134 | // @Override
135 | // public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
136 | // mFilePathCallbacks = filePathCallback;
137 | // openSelectImageDialog();
138 | // return true;
139 | // }
140 | };
141 |
142 | /**
143 | * 设置WebViewClient
144 | * 处理Url拦截事项
145 | */
146 | private WebViewClient mWebViewClient = new WebViewClient() {
147 | @Override
148 | public boolean shouldOverrideUrlLoading(WebView view, String url) {
149 | view.loadUrl(url);
150 | return true;
151 | }
152 | };
153 |
154 | @Override
155 | protected void onDestroy() {
156 |
157 | if (cdWebView != null) {
158 | cdWebView.destroy();
159 | }
160 | if (cdRootView != null && cdWebView != null) {
161 | cdRootView.removeView(cdWebView);
162 | cdRootView.removeAllViews();
163 | cdWebView = null;
164 | cdRootView = null;
165 | }
166 | SlideBackLayoutUtils.onDestroy(this);
167 | super.onDestroy();
168 | }
169 |
170 | }
171 |
--------------------------------------------------------------------------------
/app/src/main/java/com/slidbacklib/commonadapter/ListViewAdapter.java:
--------------------------------------------------------------------------------
1 | package com.slidbacklib.commonadapter;
2 |
3 | import android.view.View;
4 | import android.view.ViewGroup;
5 | import android.widget.BaseAdapter;
6 |
7 | import com.slidbacklib.commonadapter.viewholders.GodViewHolder;
8 |
9 | import java.util.ArrayList;
10 | import java.util.List;
11 |
12 | /**
13 | * 适用于ListView的 通用 Adapter
14 | */
15 | public abstract class ListViewAdapter extends BaseAdapter {
16 | /**
17 | * 数据集
18 | */
19 | protected final List mDataSet = new ArrayList<>();
20 | /**
21 | * Item Layout
22 | */
23 | private int mItemLayoutId;
24 |
25 | /**
26 | *
27 | * @param layoutId
28 | */
29 | public ListViewAdapter(int layoutId) {
30 | mItemLayoutId = layoutId;
31 | }
32 |
33 | public ListViewAdapter(int layoutId, List datas) {
34 | mItemLayoutId = layoutId;
35 | mDataSet.addAll(datas) ;
36 | }
37 |
38 | /**
39 | * @param item
40 | */
41 | public void addItem(D item) {
42 | mDataSet.add(item);
43 | notifyDataSetChanged();
44 | }
45 |
46 | /**
47 | * @param items
48 | */
49 | public void addItems(List items) {
50 | mDataSet.addAll(items);
51 | notifyDataSetChanged();
52 | }
53 |
54 | /**
55 | * @param item
56 | */
57 | public void addItemToHead(D item) {
58 | mDataSet.add(0, item);
59 | notifyDataSetChanged();
60 | }
61 |
62 | /**
63 | * @param items
64 | */
65 | public void addItemsToHead(List items) {
66 | mDataSet.addAll(0, items);
67 | notifyDataSetChanged();
68 | }
69 |
70 | /**
71 | * @param position
72 | */
73 | public void remove(int position) {
74 | mDataSet.remove(position);
75 | notifyDataSetChanged();
76 | }
77 |
78 | /**
79 | * @param item
80 | */
81 | public void remove(D item) {
82 | mDataSet.remove(item);
83 | notifyDataSetChanged();
84 | }
85 |
86 | /**
87 | * clear all data
88 | */
89 | public void clear() {
90 | mDataSet.clear();
91 | notifyDataSetChanged();
92 | }
93 |
94 | /**
95 | * @return
96 | */
97 | @Override
98 | public int getCount() {
99 | return mDataSet.size();
100 | }
101 |
102 | /**
103 | * @param position
104 | * @return
105 | */
106 | @Override
107 | public D getItem(int position) {
108 | return mDataSet.get(position);
109 | }
110 |
111 | /**
112 | * @param position
113 | * @return
114 | */
115 | @Override
116 | public long getItemId(int position) {
117 | return position;
118 | }
119 |
120 | /**
121 | * 根据View Type返回布局资源
122 | *
123 | * @param type
124 | * @return
125 | */
126 | protected int getItemLayout(int type) {
127 | return mItemLayoutId;
128 | }
129 |
130 | /**
131 | * 封装getView逻辑,将根据viewType获取布局资源、解析布局资源、创建ViewHolder等逻辑封装起来,简化使用流程
132 | *
133 | * @param position
134 | * @param convertView
135 | * @param parent
136 | * @return
137 | */
138 | @Override
139 | public View getView(int position, View convertView, ViewGroup parent) {
140 | int viewType = getItemViewType( position ) ;
141 | GodViewHolder viewHolder = GodViewHolder.get(convertView, parent, getItemLayout(viewType));
142 | // 绑定数据
143 | onBindData(viewHolder, position, getItem(position));
144 | return viewHolder.getItemView();
145 | }
146 |
147 | /**
148 | * 绑定数据到Item View上
149 | *
150 | * @param viewHolder
151 | * @param position 数据的位置
152 | * @param item 数据项
153 | */
154 | protected abstract void onBindData(GodViewHolder viewHolder, int position, D item);
155 |
156 | }
157 |
--------------------------------------------------------------------------------
/app/src/main/java/com/slidbacklib/commonadapter/RecyclerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.slidbacklib.commonadapter;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import com.slidbacklib.commonadapter.viewholders.RecyclerViewHolder;
10 |
11 | import java.util.ArrayList;
12 | import java.util.List;
13 |
14 | /**
15 | * 用于RecyclerView的Adapter
16 | */
17 | public abstract class RecyclerAdapter extends RecyclerView.Adapter {
18 |
19 | /**
20 | * 数据集
21 | */
22 | protected final List mDataSet = new ArrayList<>();
23 | /**
24 | * 单击事件
25 | */
26 | protected OnItemClickListener mOnItemClickListener;
27 | /**
28 | * Item Layout的资源id
29 | */
30 | private int mItemLayoutId;
31 |
32 | /**
33 | * @param layoutId 布局id
34 | */
35 | public RecyclerAdapter(int layoutId) {
36 | mItemLayoutId = layoutId;
37 | }
38 |
39 | /**
40 | * @param layoutId 布局id
41 | * @param datas 数据集
42 | */
43 | public RecyclerAdapter(int layoutId, List datas) {
44 | mItemLayoutId = layoutId;
45 | addItems(datas);
46 | }
47 |
48 | /**
49 | * 追加单个数据
50 | *
51 | * @param item
52 | */
53 | public void addItem(D item) {
54 | mDataSet.add(item);
55 | notifyDataSetChanged();
56 | }
57 |
58 |
59 | /**
60 | * 追加数据集
61 | *
62 | * @param items
63 | */
64 | public void addItems(List items) {
65 | mDataSet.addAll(items);
66 | notifyDataSetChanged();
67 | }
68 |
69 | /**
70 | * 添加单个数据到列表头部
71 | *
72 | * @param item
73 | */
74 | public void addItemToHead(D item) {
75 | mDataSet.add(0, item);
76 | notifyDataSetChanged();
77 | }
78 |
79 | /**
80 | * 添加数据集到列表头部
81 | *
82 | * @param items
83 | */
84 | public void addItemsToHead(List items) {
85 | mDataSet.addAll(0, items);
86 | notifyDataSetChanged();
87 | }
88 |
89 | /**
90 | * 移除某个数据
91 | *
92 | * @param position
93 | */
94 | public void remove(int position) {
95 | mDataSet.remove(position);
96 | notifyDataSetChanged();
97 | }
98 |
99 | /**
100 | * 移除某个数据项
101 | *
102 | * @param item
103 | */
104 | public void remove(D item) {
105 | mDataSet.remove(item);
106 | notifyDataSetChanged();
107 | }
108 |
109 | /**
110 | * clear all data
111 | */
112 | public void clear() {
113 | mDataSet.clear();
114 | notifyDataSetChanged();
115 | }
116 |
117 | /**
118 | * 获取指定位置的数据项
119 | *
120 | * @param position
121 | * @return
122 | */
123 | public D getItem(int position) {
124 | return mDataSet.get(position);
125 | }
126 |
127 | @Override
128 | public int getItemCount() {
129 | return mDataSet.size();
130 | }
131 |
132 | @Override
133 | public void onBindViewHolder(RecyclerViewHolder holder, int position) {
134 | final D item = getItem(position);
135 | // 绑定数据
136 | onBindData(holder, position, item);
137 | // 设置单击事件
138 | setupItemClickListener(holder, position);
139 | }
140 |
141 | /**
142 | * 解析布局资源
143 | *
144 | * @param viewGroup
145 | * @param viewType
146 | * @return
147 | */
148 | protected View inflateItemView(ViewGroup viewGroup, int viewType) {
149 | int itemLayout = getItemLayout(viewType);
150 | Context context = viewGroup.getContext();
151 | return LayoutInflater.from(context).inflate(itemLayout, viewGroup, false);
152 | }
153 |
154 | @Override
155 | public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
156 | return new RecyclerViewHolder(inflateItemView(parent, viewType));
157 | }
158 |
159 | /**
160 | * 根据Type返回布局资源
161 | *
162 | * @param type
163 | * @return
164 | */
165 | protected int getItemLayout(int type) {
166 | return mItemLayoutId;
167 | }
168 |
169 |
170 | /**
171 | * 绑定数据到Item View上
172 | *
173 | * @param viewHolder
174 | * @param position 数据的位置
175 | * @param item 数据项
176 | */
177 | protected abstract void onBindData(RecyclerViewHolder viewHolder, int position, D item);
178 |
179 |
180 | /**
181 | * @param viewHolder
182 | * @param position
183 | */
184 | protected void setupItemClickListener(RecyclerViewHolder viewHolder, final int position) {
185 | viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
186 | @Override
187 | public void onClick(View v) {
188 | if (mOnItemClickListener != null) {
189 | mOnItemClickListener.onItemClick(position);
190 | }
191 | }
192 | });
193 | }
194 |
195 | /**
196 | * 设置点击事件
197 | *
198 | * @param listener
199 | */
200 | public void setOnItemClickListener(OnItemClickListener listener) {
201 | this.mOnItemClickListener = listener;
202 | }
203 |
204 | /**
205 | * 点击事件Listener
206 | */
207 | public static interface OnItemClickListener {
208 | void onItemClick(int position);
209 | }
210 |
211 | }
212 |
--------------------------------------------------------------------------------
/app/src/main/java/com/slidbacklib/commonadapter/viewholders/GodViewHolder.java:
--------------------------------------------------------------------------------
1 | package com.slidbacklib.commonadapter.viewholders;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.graphics.Bitmap;
6 | import android.graphics.drawable.Drawable;
7 | import android.net.Uri;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.AdapterView;
12 |
13 | /**
14 | *
15 | *
16 | */
17 | public class GodViewHolder {
18 | /**
19 | * ViewHolder实现类,桥接模式适配AbsListView与RecyclerView的二维变化
20 | */
21 | ViewHolderImpl mHolderImpl ;
22 |
23 |
24 | /**
25 | * @param itemView
26 | */
27 | GodViewHolder(View itemView) {
28 | mHolderImpl = new ViewHolderImpl( itemView ) ;
29 | }
30 |
31 | /**
32 | * @param viewId
33 | * @param
34 | * @return
35 | */
36 | public T findViewById(int viewId) {
37 | return mHolderImpl.findViewById(viewId);
38 | }
39 |
40 | public Context getContext() {
41 | return mHolderImpl.mItemView.getContext() ;
42 | }
43 |
44 | /**
45 | * 获取GodViewHolder
46 | *
47 | * @param convertView
48 | * @param parent
49 | * @param layoutId
50 | * @return
51 | */
52 | public static GodViewHolder get(View convertView, ViewGroup parent, int layoutId) {
53 | GodViewHolder viewHolder = null;
54 | if (convertView == null) {
55 | convertView = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
56 | viewHolder = new GodViewHolder(convertView);
57 | convertView.setTag(viewHolder);
58 | } else {
59 | viewHolder = (GodViewHolder) convertView.getTag();
60 | }
61 |
62 | return viewHolder;
63 | }
64 |
65 |
66 | public View getItemView() {
67 | return mHolderImpl.getItemView();
68 | }
69 |
70 | public GodViewHolder setText(int viewId, int stringId) {
71 | mHolderImpl.setText(viewId, stringId);
72 | return this;
73 | }
74 |
75 | public GodViewHolder setText(int viewId, String text) {
76 | mHolderImpl.setText(viewId, text);
77 | return this;
78 | }
79 |
80 | public GodViewHolder setTextColor(int viewId, int color) {
81 | mHolderImpl.setTextColor(viewId, color);
82 | return this;
83 | }
84 |
85 | /**
86 | * @param viewId
87 | * @param color
88 | */
89 | public GodViewHolder setBackgroundColor(int viewId, int color) {
90 | mHolderImpl.setBackgroundColor(viewId, color);
91 | return this;
92 | }
93 |
94 |
95 | /**
96 | * @param viewId
97 | * @param resId
98 | */
99 | public GodViewHolder setBackgroundResource(int viewId, int resId) {
100 | mHolderImpl.setBackgroundResource(viewId, resId);
101 | return this;
102 | }
103 |
104 |
105 | /**
106 | * @param viewId
107 | * @param drawable
108 | */
109 | public GodViewHolder setBackgroundDrawable(int viewId, Drawable drawable) {
110 | mHolderImpl.setBackgroundDrawable(viewId, drawable);
111 | return this;
112 | }
113 |
114 | /**
115 | * @param viewId
116 | * @param drawable
117 | */
118 | @TargetApi(16)
119 | public GodViewHolder setBackground(int viewId, Drawable drawable) {
120 | mHolderImpl.setBackground(viewId, drawable);
121 | return this;
122 | }
123 |
124 |
125 | public GodViewHolder setImageBitmap(int viewId, Bitmap bitmap) {
126 | mHolderImpl.setImageBitmap(viewId, bitmap);
127 | return this;
128 | }
129 |
130 |
131 | public GodViewHolder setImageResource(int viewId, int resId) {
132 | mHolderImpl.setImageResource(viewId, resId);
133 | return this;
134 | }
135 |
136 | public GodViewHolder setImageDrawable(int viewId, Drawable drawable) {
137 | mHolderImpl.setImageDrawable(viewId, drawable);
138 | return this;
139 | }
140 |
141 |
142 | public GodViewHolder setImageDrawable(int viewId, Uri uri) {
143 | mHolderImpl.setImageDrawable(viewId, uri);
144 | return this;
145 | }
146 |
147 |
148 | @TargetApi(16)
149 | public GodViewHolder setImageAlpha(int viewId, int alpha) {
150 | mHolderImpl.setImageAlpha(viewId, alpha);
151 | return this;
152 | }
153 |
154 | public GodViewHolder setChecked(int viewId, boolean checked) {
155 | mHolderImpl.setChecked(viewId, checked);
156 | return this;
157 | }
158 |
159 |
160 | public GodViewHolder setProgress(int viewId, int progress) {
161 | mHolderImpl.setProgress(viewId, progress);
162 | return this;
163 | }
164 |
165 | public GodViewHolder setProgress(int viewId, int progress, int max) {
166 | mHolderImpl.setProgress(viewId, progress, max);
167 | return this;
168 | }
169 |
170 | public GodViewHolder setMax(int viewId, int max) {
171 | mHolderImpl.setMax(viewId, max);
172 | return this;
173 | }
174 |
175 | public GodViewHolder setRating(int viewId, float rating) {
176 | mHolderImpl.setRating(viewId, rating);
177 | return this;
178 | }
179 |
180 |
181 | public GodViewHolder setRating(int viewId, float rating, int max) {
182 | mHolderImpl.setRating(viewId, rating, max);
183 | return this;
184 | }
185 |
186 | public GodViewHolder setVisibility(int viewId, int visible) {
187 | mHolderImpl.setVisibility(viewId, visible);
188 | return this;
189 | }
190 |
191 | public GodViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {
192 | mHolderImpl.setOnClickListener(viewId, listener);
193 | return this;
194 | }
195 |
196 | public GodViewHolder setOnTouchListener(int viewId, View.OnTouchListener listener) {
197 | mHolderImpl.setOnTouchListener(viewId, listener);
198 | return this;
199 | }
200 |
201 | public GodViewHolder setOnLongClickListener(int viewId, View.OnLongClickListener listener) {
202 | mHolderImpl.setOnLongClickListener(viewId, listener);
203 | return this;
204 | }
205 |
206 | public GodViewHolder setOnItemClickListener(int viewId, AdapterView.OnItemClickListener listener) {
207 | mHolderImpl.setOnItemClickListener(viewId, listener);
208 | return this;
209 | }
210 |
211 |
212 | public GodViewHolder setOnItemLongClickListener(int viewId, AdapterView.OnItemLongClickListener listener) {
213 | mHolderImpl.setOnItemLongClickListener(viewId, listener);
214 | return this;
215 | }
216 |
217 |
218 | public GodViewHolder setOnItemSelectedClickListener(int viewId, AdapterView.OnItemSelectedListener listener) {
219 | mHolderImpl.setOnItemSelectedClickListener(viewId, listener);
220 | return this;
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/app/src/main/java/com/slidbacklib/commonadapter/viewholders/RecyclerViewHolder.java:
--------------------------------------------------------------------------------
1 | package com.slidbacklib.commonadapter.viewholders;
2 | import android.annotation.TargetApi;
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.drawable.Drawable;
6 | import android.net.Uri;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.view.View;
9 | import android.widget.AdapterView;
10 |
11 | /**
12 | * 适用于RecyclerView的ViewHolder
13 | */
14 | public class RecyclerViewHolder extends RecyclerView.ViewHolder {
15 | /**
16 | * ViewHolder实现类,桥接模式适配AbsListView与RecyclerView的二维变化
17 | */
18 | ViewHolderImpl mHolderImpl ;
19 |
20 | /**
21 | *
22 | * @param itemView
23 | */
24 | public RecyclerViewHolder(View itemView) {
25 | super(itemView);
26 | mHolderImpl = new ViewHolderImpl( itemView ) ;
27 | }
28 |
29 | public Context getContext() {
30 | return mHolderImpl.mItemView.getContext() ;
31 | }
32 |
33 | /**
34 | * @param viewId
35 | * @param
36 | * @return
37 | */
38 | public T findViewById(int viewId) {
39 | return mHolderImpl.findViewById(viewId);
40 | }
41 |
42 | public View getItemView() {
43 | return mHolderImpl.getItemView();
44 | }
45 |
46 | public RecyclerViewHolder setText(int viewId, int stringId) {
47 | mHolderImpl.setText(viewId, stringId);
48 | return this;
49 | }
50 |
51 | public RecyclerViewHolder setText(int viewId, String text) {
52 | mHolderImpl.setText(viewId, text);
53 | return this;
54 | }
55 |
56 | public RecyclerViewHolder setTextColor(int viewId, int color) {
57 | mHolderImpl.setTextColor(viewId, color);
58 | return this;
59 | }
60 |
61 | /**
62 | * @param viewId
63 | * @param color
64 | */
65 | public RecyclerViewHolder setBackgroundColor(int viewId, int color) {
66 | mHolderImpl.setBackgroundColor(viewId, color);
67 | return this;
68 | }
69 |
70 |
71 | /**
72 | * @param viewId
73 | * @param resId
74 | */
75 | public RecyclerViewHolder setBackgroundResource(int viewId, int resId) {
76 | mHolderImpl.setBackgroundResource(viewId, resId);
77 | return this;
78 | }
79 |
80 |
81 | /**
82 | * @param viewId
83 | * @param drawable
84 | */
85 | public RecyclerViewHolder setBackgroundDrawable(int viewId, Drawable drawable) {
86 | mHolderImpl.setBackgroundDrawable(viewId, drawable);
87 | return this;
88 | }
89 |
90 | /**
91 | * @param viewId
92 | * @param drawable
93 | */
94 | @TargetApi(16)
95 | public RecyclerViewHolder setBackground(int viewId, Drawable drawable) {
96 | mHolderImpl.setBackground(viewId, drawable);
97 | return this;
98 | }
99 |
100 |
101 | public RecyclerViewHolder setImageBitmap(int viewId, Bitmap bitmap) {
102 | mHolderImpl.setImageBitmap(viewId, bitmap);
103 | return this;
104 | }
105 |
106 |
107 | public RecyclerViewHolder setImageResource(int viewId, int resId) {
108 | mHolderImpl.setImageResource(viewId, resId);
109 | return this;
110 | }
111 |
112 | public RecyclerViewHolder setImageDrawable(int viewId, Drawable drawable) {
113 | mHolderImpl.setImageDrawable(viewId, drawable);
114 | return this;
115 | }
116 |
117 |
118 | public RecyclerViewHolder setImageDrawable(int viewId, Uri uri) {
119 | mHolderImpl.setImageDrawable(viewId, uri);
120 | return this;
121 | }
122 |
123 |
124 | @TargetApi(16)
125 | public RecyclerViewHolder setImageAlpha(int viewId, int alpha) {
126 | mHolderImpl.setImageAlpha(viewId, alpha);
127 | return this;
128 | }
129 |
130 | public RecyclerViewHolder setChecked(int viewId, boolean checked) {
131 | mHolderImpl.setChecked(viewId, checked);
132 | return this;
133 | }
134 |
135 |
136 | public RecyclerViewHolder setProgress(int viewId, int progress) {
137 | mHolderImpl.setProgress(viewId, progress);
138 | return this;
139 | }
140 |
141 | public RecyclerViewHolder setProgress(int viewId, int progress, int max) {
142 | mHolderImpl.setProgress(viewId, progress, max);
143 | return this;
144 | }
145 |
146 | public RecyclerViewHolder setMax(int viewId, int max) {
147 | mHolderImpl.setMax(viewId, max);
148 | return this;
149 | }
150 |
151 | public RecyclerViewHolder setRating(int viewId, float rating) {
152 | mHolderImpl.setRating(viewId, rating);
153 | return this;
154 | }
155 |
156 | public RecyclerViewHolder setVisibility(int viewId, int visible) {
157 | mHolderImpl.setVisibility(viewId, visible);
158 | return this;
159 | }
160 |
161 |
162 | public RecyclerViewHolder setRating(int viewId, float rating, int max) {
163 | mHolderImpl.setRating(viewId, rating, max);
164 | return this;
165 | }
166 |
167 | public RecyclerViewHolder setOnClickListener(int viewId, View.OnClickListener listener) {
168 | mHolderImpl.setOnClickListener(viewId, listener);
169 | return this;
170 | }
171 |
172 | public RecyclerViewHolder setOnTouchListener(int viewId, View.OnTouchListener listener) {
173 | mHolderImpl.setOnTouchListener(viewId, listener);
174 | return this;
175 | }
176 |
177 |
178 | public RecyclerViewHolder setOnLongClickListener(int viewId, View.OnLongClickListener listener) {
179 | mHolderImpl.setOnLongClickListener(viewId, listener);
180 | return this;
181 | }
182 |
183 | public RecyclerViewHolder setOnItemClickListener(int viewId, AdapterView.OnItemClickListener listener) {
184 | mHolderImpl.setOnItemClickListener(viewId, listener);
185 | return this;
186 | }
187 |
188 |
189 | public RecyclerViewHolder setOnItemLongClickListener(int viewId, AdapterView.OnItemLongClickListener listener) {
190 | mHolderImpl.setOnItemLongClickListener(viewId, listener);
191 | return this;
192 | }
193 |
194 |
195 | public RecyclerViewHolder setOnItemSelectedClickListener(int viewId, AdapterView.OnItemSelectedListener listener) {
196 | mHolderImpl.setOnItemSelectedClickListener(viewId, listener);
197 | return this;
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/app/src/main/java/com/slidbacklib/commonadapter/viewholders/ViewHolderImpl.java:
--------------------------------------------------------------------------------
1 | package com.slidbacklib.commonadapter.viewholders;
2 |
3 | import android.annotation.TargetApi;
4 | import android.graphics.Bitmap;
5 | import android.graphics.drawable.Drawable;
6 | import android.net.Uri;
7 | import android.util.SparseArray;
8 | import android.view.View;
9 | import android.widget.AdapterView;
10 | import android.widget.Checkable;
11 | import android.widget.ImageView;
12 | import android.widget.ProgressBar;
13 | import android.widget.RatingBar;
14 | import android.widget.TextView;
15 |
16 | /**
17 | * ViewHolder操作子视图的实现类
18 | */
19 | public class ViewHolderImpl {
20 |
21 | /**
22 | * 缓存子视图,key为view id, 值为View。
23 | */
24 | private SparseArray mCahceViews = new SparseArray();
25 | /**
26 | * Item View
27 | */
28 | View mItemView;
29 |
30 | /**
31 | * @param itemView
32 | */
33 | ViewHolderImpl(View itemView) {
34 | mItemView = itemView;
35 | }
36 |
37 | public View getItemView() {
38 | return mItemView;
39 | }
40 |
41 | /**
42 | * @param viewId
43 | * @param
44 | * @return
45 | */
46 | public T findViewById(int viewId) {
47 | View target = mCahceViews.get(viewId);
48 | if (target == null) {
49 | target = mItemView.findViewById(viewId);
50 | mCahceViews.put(viewId, target);
51 | }
52 | return (T) target;
53 | }
54 |
55 |
56 | public void setText(int viewId, int stringId) {
57 | TextView textView = findViewById(viewId);
58 | textView.setText(stringId);
59 | }
60 |
61 | public void setText(int viewId, String text) {
62 | TextView textView = findViewById(viewId);
63 | textView.setText(text);
64 | }
65 |
66 | public void setTextColor(int viewId, int color) {
67 | TextView textView = findViewById(viewId);
68 | textView.setTextColor(color);
69 | }
70 |
71 | /**
72 | * @param viewId
73 | * @param color
74 | */
75 | public void setBackgroundColor(int viewId, int color) {
76 | View target = findViewById(viewId);
77 | target.setBackgroundColor(color);
78 |
79 | }
80 |
81 |
82 | /**
83 | * @param viewId
84 | * @param resId
85 | */
86 | public void setBackgroundResource(int viewId, int resId) {
87 | View target = findViewById(viewId);
88 | target.setBackgroundResource(resId);
89 | }
90 |
91 |
92 | /**
93 | * @param viewId
94 | * @param drawable
95 | */
96 | public void setBackgroundDrawable(int viewId, Drawable drawable) {
97 | View target = findViewById(viewId);
98 | target.setBackgroundDrawable(drawable);
99 | }
100 |
101 | /**
102 | * @param viewId
103 | * @param drawable
104 | */
105 | @TargetApi(16)
106 | public void setBackground(int viewId, Drawable drawable) {
107 | View target = findViewById(viewId);
108 | target.setBackground(drawable);
109 | }
110 |
111 |
112 | public void setImageBitmap(int viewId, Bitmap bitmap) {
113 | ImageView target = findViewById(viewId);
114 | target.setImageBitmap(bitmap);
115 | }
116 |
117 |
118 | public void setImageResource(int viewId, int resId) {
119 | ImageView target = findViewById(viewId);
120 | target.setImageResource(resId);
121 | }
122 |
123 |
124 | public void setImageDrawable(int viewId, Drawable drawable) {
125 | ImageView target = findViewById(viewId);
126 | target.setImageDrawable(drawable);
127 | }
128 |
129 |
130 | public void setImageDrawable(int viewId, Uri uri) {
131 | ImageView target = findViewById(viewId);
132 | target.setImageURI(uri);
133 | }
134 |
135 |
136 | @TargetApi(16)
137 | public void setImageAlpha(int viewId, int alpha) {
138 | ImageView target = findViewById(viewId);
139 | target.setImageAlpha(alpha);
140 | }
141 |
142 | public void setChecked(int viewId, boolean checked) {
143 | Checkable checkable = findViewById(viewId);
144 | checkable.setChecked(checked);
145 | }
146 |
147 |
148 | public void setProgress(int viewId, int progress) {
149 | ProgressBar view = findViewById(viewId);
150 | view.setProgress(progress);
151 | }
152 |
153 | public void setProgress(int viewId, int progress, int max) {
154 | ProgressBar view = findViewById(viewId);
155 | view.setMax(max);
156 | view.setProgress(progress);
157 | }
158 |
159 | public void setMax(int viewId, int max) {
160 | ProgressBar view = findViewById(viewId);
161 | view.setMax(max);
162 | }
163 |
164 | public void setRating(int viewId, float rating) {
165 | RatingBar view = findViewById(viewId);
166 | view.setRating(rating);
167 | }
168 |
169 | public void setVisibility(int viewId, int visible) {
170 | View view = findViewById(viewId);
171 | view.setVisibility(visible);
172 | }
173 |
174 |
175 | public void setRating(int viewId, float rating, int max) {
176 | RatingBar view = findViewById(viewId);
177 | view.setMax(max);
178 | view.setRating(rating);
179 | }
180 |
181 | public void setOnClickListener(int viewId, View.OnClickListener listener) {
182 | View view = findViewById(viewId);
183 | view.setOnClickListener(listener);
184 |
185 | }
186 |
187 | public void setOnTouchListener(int viewId, View.OnTouchListener listener) {
188 | View view = findViewById(viewId);
189 | view.setOnTouchListener(listener);
190 | }
191 |
192 |
193 | public void setOnLongClickListener(int viewId, View.OnLongClickListener listener) {
194 | View view = findViewById(viewId);
195 | view.setOnLongClickListener(listener);
196 | }
197 |
198 | public void setOnItemClickListener(int viewId, AdapterView.OnItemClickListener listener) {
199 | AdapterView view = findViewById(viewId);
200 | view.setOnItemClickListener(listener);
201 | }
202 |
203 |
204 | public void setOnItemLongClickListener(int viewId, AdapterView.OnItemLongClickListener listener) {
205 | AdapterView view = findViewById(viewId);
206 | view.setOnItemLongClickListener(listener);
207 | }
208 |
209 |
210 | public void setOnItemSelectedClickListener(int viewId, AdapterView.OnItemSelectedListener listener) {
211 | AdapterView view = findViewById(viewId);
212 | view.setOnItemSelectedListener(listener);
213 | }
214 | }
215 |
--------------------------------------------------------------------------------
/app/src/main/java/com/slidbacklib/utils/SlideBackLayoutUtils.java:
--------------------------------------------------------------------------------
1 | package com.slidbacklib.utils;
2 |
3 | import android.app.Activity;
4 |
5 | import com.slidbacklib.App;
6 | import com.slideback.SlideBackHelper;
7 | import com.slideback.SlideConfig;
8 | import com.slideback.callbak.OnSlideListenerAdapter;
9 | import com.slideback.widget.SlideBackLayout;
10 |
11 | import java.util.HashMap;
12 |
13 | /**
14 | * ===============================
15 | * 描 述:SlideBackLayoutUtils
16 | * 作 者:pjw
17 | * 创建日期:2017/12/20 17:28
18 | * ===============================
19 | */
20 | public class SlideBackLayoutUtils {
21 |
22 | private static HashMap mBackLayoutHashMap = new HashMap<>(3);
23 |
24 | /**
25 | * 设置侧滑返回,默认配置
26 | */
27 | public static void sideBack(Activity activity) {
28 | sideBack(activity, getDefaultSlideConfig(), null);
29 | }
30 |
31 | public static void sideBack(Activity activity, SlideConfig slideConfig, OnSlideListenerAdapter adapter) {
32 | SlideBackHelper slideBackHelper = new SlideBackHelper();
33 | SlideBackLayout slideBackLayout = slideBackHelper.attach(
34 | // 当前Activity
35 | activity,
36 | //ActivityHelper
37 | App.sApp.getActivityHelper(),
38 | // 参数的配置
39 | slideConfig,
40 | // 滑动的监听
41 | adapter);
42 | if (slideBackLayout == null) return;
43 | //添加到集合中
44 | mBackLayoutHashMap.put(activity, slideBackLayout);
45 | //添加到栈
46 | App.sApp.getActivityHelper().setActivityInfo(activity, slideBackLayout, slideBackHelper);
47 | // //边缘响应的最大值
48 | // slideBackLayout.setEdgeRangePercent(0.2f);
49 | // //非快速滑动,关闭页面的最小值
50 | // slideBackLayout.setSlideOutRangePercent(0.3f);
51 | // //是否关闭全局侧滑,默认开启全局侧滑
52 | // slideBackLayout.edgeOnly(true);
53 | // //是否关闭侧滑,默认开启侧滑
54 | // slideBackLayout.lock(false);
55 | }
56 |
57 | /**
58 | * 获取默认配置
59 | */
60 | public static SlideConfig getDefaultSlideConfig() {
61 | // 参数的配置
62 | return new SlideConfig()
63 | // 屏幕是否旋转
64 | .setRotateScreen(false)
65 | // 是否关闭全局侧滑
66 | .setEdgeOnly(true)
67 | // 是否关闭侧滑
68 | .setLock(false)
69 | // 边缘响应滑动区域的最大值 0~1
70 | .setEdgePercent(0.2f)
71 | // 非快速滑动,关闭页面的最小值 0~1
72 | .setSlideOutPercent(0.4f);
73 | }
74 |
75 | public static void onDestroy(Activity activity) {
76 | //Activity销毁调用方法
77 | SlideBackLayout slideBackLayout = mBackLayoutHashMap.get(activity);
78 | if (slideBackLayout != null) {
79 | slideBackLayout.isComingToFinish();
80 | mBackLayoutHashMap.remove(activity);
81 | }
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/app/src/main/java/com/slidbacklib/utils/StringUtils.java:
--------------------------------------------------------------------------------
1 | package com.slidbacklib.utils;
2 |
3 | import java.util.ArrayList;
4 |
5 | /**
6 | * ===============================
7 | * 描 述:
8 | * 作 者:pjw
9 | * 创建日期:2017/11/1 13:48
10 | * ===============================
11 | */
12 | public class StringUtils {
13 |
14 | public static ArrayList getDatas(int count) {
15 | ArrayList arrayList = new ArrayList<>(count);
16 | for (int i = 0; i < count; i++) {
17 | arrayList.add("i:" + i);
18 | }
19 | return arrayList;
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/icon_title_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/drawable-xxhdpi/icon_title_back.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/icon_titlebar_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/drawable-xxhdpi/icon_titlebar_close.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/percent_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/drawable-xxhdpi/percent_arrow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/title_back_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/drawable-xxhdpi/title_back_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/person_item_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/webview_progress_style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
11 |
12 |
13 | -
14 |
15 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_list_data.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_scroll_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
17 |
18 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_web_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
23 |
24 |
31 |
32 |
41 |
42 |
53 |
54 |
62 |
63 |
76 |
77 |
82 |
83 |
84 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
102 |
103 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_list_data.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
26 |
27 |
39 |
40 |
46 |
47 |
52 |
53 |
54 |
60 |
61 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
8 | #FFFBFBFB
9 | #FFFFFFFF
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SlidBackLib
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | apply from :'config.gradle'
4 |
5 | buildscript {
6 | repositories {
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:2.3.2'
11 |
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 | tasks.withType(JavaCompile) {
22 | options.encoding = "UTF-8"
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
--------------------------------------------------------------------------------
/config.gradle:
--------------------------------------------------------------------------------
1 | ext {
2 | android = [
3 | compileSdkVersion: 26,
4 | buildToolsVersion: "26.0.2",
5 | minSdkVersion : 14,
6 | targetSdkVersion : 26,
7 | versionCode : 171031,
8 | versionName : "0.0.1"
9 | ]
10 | version = [
11 | androidSupportSdkVersion: "26.+",
12 | retrofitSdkVersion : "2.2.0",
13 | dagger2SdkVersion : "2.9",
14 | butterknifeSdkVersion : "8.7.0",
15 | rxlifecycleSdkVersion : "1.0",
16 | rxlifecycle2SdkVersion : "2.0.1",
17 | espressoSdkVersion : "2.2.2",
18 | canarySdkVersion : "1.5"
19 | ]
20 |
21 | dependencies = [
22 | //support
23 | "appcompat-v7" : "com.android.support:appcompat-v7:${version["androidSupportSdkVersion"]}",
24 | "design" : "com.android.support:design:${version["androidSupportSdkVersion"]}",
25 | "support-v4" : "com.android.support:support-v4:${version["androidSupportSdkVersion"]}",
26 | "cardview-v7" : "com.android.support:cardview-v7:${version["androidSupportSdkVersion"]}",
27 | "annotations" : "com.android.support:support-annotations:${version["androidSupportSdkVersion"]}",
28 | "recyclerview-v7" : "com.android.support:recyclerview-v7:${version["androidSupportSdkVersion"]}",
29 | "support-core-ui" : "com.android.support:support-core-ui:${version["androidSupportSdkVersion"]}",
30 | "support-compat" : "com.android.support:support-compat:${version["androidSupportSdkVersion"]}",
31 |
32 | //network
33 | "retrofit" : "com.squareup.retrofit2:retrofit:${version["retrofitSdkVersion"]}",
34 | "retrofit-converter-gson" : "com.squareup.retrofit2:converter-gson:${version["retrofitSdkVersion"]}",
35 | "retrofit-adapter-rxjava" : "com.squareup.retrofit2:adapter-rxjava:${version["retrofitSdkVersion"]}",
36 | "retrofit-adapter-rxjava2" : "com.squareup.retrofit2:adapter-rxjava2:${version["retrofitSdkVersion"]}",
37 | "okhttp3" : "com.squareup.okhttp3:okhttp:3.7.0",
38 | "okhttp-urlconnection" : "com.squareup.okhttp:okhttp-urlconnection:2.0.0",
39 | "glide" : "com.github.bumptech.glide:glide:3.8.0",
40 | "picasso" : "com.squareup.picasso:picasso:2.5.2",
41 |
42 | //view
43 | "autolayout" : "com.zhy:autolayout:1.4.5",
44 | "butterknife" : "com.jakewharton:butterknife:${version["butterknifeSdkVersion"]}",
45 | "annotationProcessor" : "com.jakewharton:butterknife-compiler:${version["butterknifeSdkVersion"]}",
46 | "butterknife-compiler" : "com.jakewharton:butterknife-compiler:${version["butterknifeSdkVersion"]}",
47 | "pickerview" : "com.bigkoo:pickerview:2.0.8",
48 | "photoview" : "com.github.chrisbanes.photoview:library:1.2.3",
49 | "numberprogressbar" : "com.daimajia.numberprogressbar:library:1.2@aar",
50 | "nineoldandroids" : "com.nineoldandroids:library:2.4.0",
51 | "loading-indicator" : 'com.wang.avi:library:2.1.3',
52 | "paginate" : "com.github.markomilos:paginate:0.5.1",
53 | "constraint-layout" : 'com.android.support.constraint:constraint-layout:1.0.2',
54 |
55 | //rx1
56 | "rxandroid" : "io.reactivex:rxandroid:1.2.1",
57 | "rxjava" : "io.reactivex:rxjava:1.2.9",
58 | "rxlifecycle" : "com.trello:rxlifecycle:${version["rxlifecycleSdkVersion"]}",
59 | "rxlifecycle-components" : "com.trello:rxlifecycle-components:${version["rxlifecycleSdkVersion"]}",
60 | "rxcache" : "com.github.VictorAlbertos.RxCache:runtime:1.7.0-1.x",
61 | "rxcache-jolyglot-gson" : "com.github.VictorAlbertos.Jolyglot:gson:0.0.3",
62 | "rxbinding-recyclerview-v7": "com.jakewharton.rxbinding:rxbinding-recyclerview-v7:1.0.1",
63 | "rxpermissions" : "com.tbruyelle.rxpermissions:rxpermissions:0.9.3@aar",
64 | "rxerrorhandler" : "me.jessyan:rxerrorhandler:1.0.1",
65 |
66 | //rx2
67 | "rxandroid2" : "io.reactivex.rxjava2:rxandroid:2.0.1",
68 | "rxjava2" : "io.reactivex.rxjava2:rxjava:2.1.0",
69 | "rxlifecycle2" : "com.trello.rxlifecycle2:rxlifecycle:${version["rxlifecycle2SdkVersion"]}",
70 | "rxlifecycle2-components" : "com.trello.rxlifecycle2:rxlifecycle-components:${version["rxlifecycle2SdkVersion"]}",
71 | "rxcache2" : "com.github.VictorAlbertos.RxCache:runtime:1.8.0-2.x",
72 | "rxpermissions2" : "com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar",
73 | "rxerrorhandler2" : "me.jessyan:rxerrorhandler:2.0.1",
74 |
75 | //tools
76 | "dagger2" : "com.google.dagger:dagger:${version["dagger2SdkVersion"]}",
77 | "dagger2-compiler" : "com.google.dagger:dagger-compiler:${version["dagger2SdkVersion"]}",
78 | "androideventbus" : "org.simple:androideventbus:1.0.5.1",//org.greenrobot:eventbus:3.0.0
79 | "otto" : "com.squareup:otto:1.3.8",
80 | "gson" : "com.google.code.gson:gson:2.8.0",
81 | "multidex" : "com.android.support:multidex:1.0.1",
82 | "javax.annotation" : "javax.annotation:jsr250-api:1.0",
83 |
84 | //test
85 | "junit" : "junit:junit:4.12",
86 | "androidJUnitRunner" : "android.support.test.runner.AndroidJUnitRunner",
87 | "runner" : "com.android.support.test:runner:0.5",
88 | "espresso-core" : "com.android.support.test.espresso:espresso-core:${version["espressoSdkVersion"]}",
89 | "espresso-contrib" : "com.android.support.test.espresso:espresso-contrib:${version["espressoSdkVersion"]}",
90 | "espresso-intents" : "com.android.support.test.espresso:espresso-intents:${version["espressoSdkVersion"]}",
91 | "mockito-core" : "org.mockito:mockito-core:1.+",
92 | "timber" : "com.jakewharton.timber:timber:4.5.1",
93 | "canary-debug" : "com.squareup.leakcanary:leakcanary-android:${version["canarySdkVersion"]}",
94 | "canary-release" : "com.squareup.leakcanary:leakcanary-android-no-op:${version["canarySdkVersion"]}",
95 | "umeng-analytics" : "com.umeng.analytics:analytics:6.0.1",
96 |
97 | //other
98 | "logger" : "com.orhanobut:logger:1.15",
99 |
100 | //bugLy
101 | "bugly-crashreport" : "com.tencent.bugly:crashreport:2.6.5",
102 | "bugly-nativecrashreport" : "com.tencent.bugly:nativecrashreport:3.3.0",
103 | "bugly-crashreport_upgrade": "com.tencent.bugly:crashreport_upgrade:1.3.1",
104 |
105 | //aop
106 | "aspectjrt" : "org.aspectj:aspectjrt:1.8.9",
107 | "aspectjtools" : "org.aspectj:aspectjtools:1.8.9",
108 | "aspectjweaver" : "org.aspectj:aspectjweaver:1.8.9",
109 |
110 | //location
111 | "location-gd" : "com.amap.api:location:3.3.0",
112 | "location-search-gd" : "com.amap.api:search:5.2.1"
113 |
114 | ]
115 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pujunwu/SlidBackLib/8ecfe6e85b7a186f27fd4666bb4587024962bab3/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Dec 26 15:31:13 CST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':sideBackLibrary'
2 |
--------------------------------------------------------------------------------
/sideBackLibrary/.gitignore:
--------------------------------------------------------------------------------
1 | # Mac OS X
2 |
3 | .DS_Store
4 | .AppleDouble
5 | .LSOverride
6 |
7 | # Icon must end with two \r
8 | Icon
9 |
10 |
11 | # Thumbnails
12 | ._*
13 |
14 | # Files that might appear in the root of a volume
15 | .DocumentRevisions-V100
16 | .fseventsd
17 | .Spotlight-V100
18 | .TemporaryItems
19 | .Trashes
20 | .VolumeIcon.icns
21 |
22 | # Directories potentially created on remote AFP share
23 | .AppleDB
24 | .AppleDesktop
25 | Network Trash Folder
26 | Temporary Items
27 | .apdisk
28 |
29 |
30 | # Android
31 |
32 | # Built application files
33 | *.apk
34 | *.ap_
35 |
36 | # Files for the Dalvik VM
37 | *.dex
38 |
39 | # Java class files
40 | *.class
41 |
42 | # Generated files
43 | bin/
44 | gen/
45 |
46 | # Gradle files
47 | .gradle/
48 | build/
49 | /gradle/
50 | /gradlew*
51 | /.idea
52 | /.idea/workspace.xml
53 |
54 | # Local configuration file (sdk path, etc)
55 | local.properties
56 |
57 | # Proguard folder generated by Eclipse
58 | proguard/
59 |
60 | # Log Files
61 | *.log
62 |
63 | # Android Studio Navigation editor temp files
64 | .navigation/
65 | /tbreader.iml
66 |
67 | # Android
68 | project.properties
69 | out
70 | captures
71 |
72 | # IntelliJ IDEA
73 | .idea
74 | *.iml
75 | *.ipl
76 | *.iws
77 |
--------------------------------------------------------------------------------
/sideBackLibrary/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion rootProject.ext.android["compileSdkVersion"]
5 | buildToolsVersion rootProject.ext.android["buildToolsVersion"]
6 |
7 | defaultConfig {
8 | minSdkVersion rootProject.ext.android["minSdkVersion"]
9 | targetSdkVersion rootProject.ext.android["targetSdkVersion"]
10 | versionCode rootProject.ext.android["versionCode"]
11 | versionName rootProject.ext.android["versionName"]
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile fileTree(dir: 'libs', include: ['*.jar'])
23 | compile rootProject.ext.dependencies["support-v4"]
24 | }
25 |
--------------------------------------------------------------------------------
/sideBackLibrary/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/LeeHong/Develop/AndroidDev/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/java/com/slideback/ActivityHelper.java:
--------------------------------------------------------------------------------
1 | package com.slideback;
2 |
3 | import android.app.Activity;
4 | import android.app.Application;
5 | import android.os.Bundle;
6 | import android.util.Log;
7 |
8 | import com.slideback.widget.SlideBackLayout;
9 |
10 | import java.util.Stack;
11 |
12 | /**
13 | * Created by Oubowu on 2016/9/20 3:28.
14 | */
15 | public class ActivityHelper implements Application.ActivityLifecycleCallbacks {
16 |
17 | private static Stack mActivityStack;
18 |
19 | public ActivityHelper() {
20 | }
21 |
22 | @Override
23 | public void onActivityCreated(Activity activity, Bundle bundle) {
24 | if (mActivityStack == null) {
25 | mActivityStack = new Stack<>();
26 | }
27 | mActivityStack.add(new ActivityEntity(activity));
28 | }
29 |
30 | @Override
31 | public void onActivityStarted(Activity activity) {
32 |
33 | }
34 |
35 | @Override
36 | public void onActivityResumed(Activity activity) {
37 |
38 | }
39 |
40 | @Override
41 | public void onActivityPaused(Activity activity) {
42 |
43 | }
44 |
45 | @Override
46 | public void onActivityStopped(Activity activity) {
47 |
48 | }
49 |
50 | @Override
51 | public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
52 |
53 | }
54 |
55 | @Override
56 | public void onActivityDestroyed(Activity activity) {
57 | // Log.e("TAG", "ActivityHelper-销毁: " + activity);
58 | postRemoveActivity(activity);
59 | }
60 |
61 | /**
62 | * 获取上一个页面
63 | */
64 | public Activity getPreActivity() {
65 | if (mActivityStack == null) {
66 | return null;
67 | }
68 | int size = mActivityStack.size();
69 | if (size < 2) {
70 | return null;
71 | }
72 | return mActivityStack.elementAt(size - 2).mActivity;
73 | }
74 |
75 | /**
76 | * 获取下一个页面
77 | */
78 | public ActivityEntity getNextActivity(Activity activity) {
79 | int current = getActivityEntityIndex(activity);
80 | if (current == -1) return null;
81 | int size = mActivityStack.size();
82 | if (size < 2 || size - 1 <= current) {
83 | return null;
84 | }
85 | return mActivityStack.elementAt(current + 1);
86 | }
87 |
88 |
89 | // /**
90 | // * 获取上一个页面
91 | // */
92 | // public Activity getPreActivity(SlideBackLayout slideBackLayout) {
93 | // if (mActivityStack == null) {
94 | // return null;
95 | // }
96 | // int size = mActivityStack.size();
97 | // if (size < 2) {
98 | // return null;
99 | // }
100 | // int index = 0;
101 | // for (int i = 0; i < size; i++) {
102 | // ActivityEntity entity = mActivityStack.elementAt(i);
103 | // if (entity != null && entity.mSlideBackLayout == slideBackLayout) {
104 | // index = i;
105 | // break;
106 | // }
107 | // }
108 | // if (index - 2 >= 0) {
109 | // return mActivityStack.elementAt(index - 2).mActivity;
110 | // }
111 | // return null;
112 | // }
113 |
114 | public void finishAllActivity() {
115 | if (mActivityStack == null) {
116 | return;
117 | }
118 | for (ActivityEntity entity : mActivityStack) {
119 | if (entity.mSlideBackHelper != null)
120 | entity.mSlideBackHelper.onDestroy();
121 | entity.mActivity.finish();
122 | }
123 | }
124 |
125 | public void printAllActivity() {
126 | if (mActivityStack == null) {
127 | return;
128 | }
129 | for (int i = 0; i < mActivityStack.size(); i++) {
130 | Log.e("TAG", "位置" + i + ": " + mActivityStack.get(i));
131 | }
132 | }
133 |
134 | /**
135 | * 强制删掉activity,用于用户快速滑动页面的时候,因为页面还没来得及destroy导致的问题
136 | *
137 | * @param activity 删掉的activity
138 | */
139 | void postRemoveActivity(Activity activity) {
140 | if (mActivityStack == null) {
141 | return;
142 | }
143 | //获取下一个页面
144 | // ActivityEntity entityNext = getNextActivity(activity);
145 | // if (entityNext != null && entityNext.mSlideBackLayout != null) {
146 | // entityNext.mSlideBackLayout.setPreContentDestroy();
147 | // }
148 | ActivityEntity entity = getActivityEntity(activity);
149 | if (entity != null && entity.mSlideBackHelper != null) {
150 | entity.mSlideBackHelper.onDestroy();
151 | entity.mActivity = null;
152 | entity.mSlideBackLayout = null;
153 | entity.mSlideBackHelper = null;
154 | }
155 | mActivityStack.remove(entity);
156 | }
157 |
158 | private ActivityEntity getActivityEntity(Activity mActivity) {
159 | if (mActivity == null) return null;
160 | for (ActivityEntity entity : mActivityStack) {
161 | if (mActivity == entity.mActivity) return entity;
162 | }
163 | return null;
164 | }
165 |
166 | private int getActivityEntityIndex(Activity mActivity) {
167 | if (mActivity == null) return -1;
168 | for (int i = 0, size = mActivityStack.size(); i < size; i++) {
169 | if (mActivity == mActivityStack.elementAt(i).mActivity) return i;
170 | }
171 | return -1;
172 | }
173 |
174 | public void setActivityInfo(Activity mActivity, SlideBackLayout mSlideBackLayout, SlideBackHelper mSlideBackHelper) {
175 | ActivityEntity entity = getActivityEntity(mActivity);
176 | entity.mSlideBackHelper = mSlideBackHelper;
177 | entity.mSlideBackLayout = mSlideBackLayout;
178 | }
179 |
180 | private class ActivityEntity {
181 | Activity mActivity;
182 | SlideBackLayout mSlideBackLayout;
183 | SlideBackHelper mSlideBackHelper;
184 |
185 | ActivityEntity(Activity mActivity) {
186 | this(mActivity, null);
187 | }
188 |
189 | ActivityEntity(Activity mActivity, SlideBackLayout mSlideBackLayout) {
190 | this(mActivity, mSlideBackLayout, null);
191 | }
192 |
193 | ActivityEntity(Activity mActivity, SlideBackLayout mSlideBackLayout, SlideBackHelper mSlideBackHelper) {
194 | this.mActivity = mActivity;
195 | this.mSlideBackLayout = mSlideBackLayout;
196 | this.mSlideBackHelper = mSlideBackHelper;
197 | }
198 | }
199 |
200 |
201 | }
202 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/java/com/slideback/SlideBackHelper.java:
--------------------------------------------------------------------------------
1 | package com.slideback;
2 |
3 | import android.app.Activity;
4 | import android.graphics.drawable.Drawable;
5 | import android.os.Handler;
6 | import android.os.Looper;
7 | import android.support.annotation.NonNull;
8 | import android.support.annotation.Nullable;
9 | import android.util.Log;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.LinearLayout;
13 |
14 | import com.slideback.callbak.OnInternalStateListener;
15 | import com.slideback.callbak.OnSlideListener;
16 | import com.slideback.widget.SlideBackLayout;
17 |
18 | /**
19 | * Created by Oubowu on 2016/9/22 0022 14:31.
20 | * 侧滑处理
21 | */
22 | // TODO: 2016/9/24 添加了上个页面的布局,如果页面有Toolbar的话其不随屏幕旋转而大小变化,永远维持进入时的宽高比
23 | public class SlideBackHelper {
24 |
25 | public static ViewGroup getDecorView(Activity activity) {
26 | if (activity == null || activity.getWindow() == null) return null;
27 | View view = activity.getWindow().getDecorView();
28 | if (view == null) return null;
29 | return (ViewGroup) view;
30 | }
31 |
32 | public static Drawable getDecorViewDrawable(Activity activity) {
33 | ViewGroup viewGroup = getDecorView(activity);
34 | if (viewGroup == null) return null;
35 | return viewGroup.getBackground();
36 | }
37 |
38 | public static View getContentView(Activity activity) {
39 | ViewGroup viewGroup = getDecorView(activity);
40 | if (viewGroup == null) return null;
41 | return viewGroup.getChildAt(0);
42 | }
43 |
44 | private ActivityHelper helper;//Activity管理对象
45 | private Activity curActivity;//当前承载SlideBackHelper的Activity
46 | private Activity preActivity;//当前Activity的上一个Activity
47 | private OnSlideListener listener;//事件回调
48 | private SlideConfig config;//配置信息
49 | private ViewGroup currentContentView;//当前Activity显示的view
50 | private View preContentView;//上一个Activity显示的view
51 |
52 | /**
53 | * 附着Activity,实现侧滑
54 | *
55 | * @param activity 当前Activity
56 | * @param activityHelper Activity栈管理类
57 | * @param slideConfig 参数配置
58 | * @param slideListener 滑动的监听
59 | * @return 处理侧滑的布局,提高方法动态设置滑动相关参数
60 | */
61 | public SlideBackLayout attach(@NonNull Activity activity, @NonNull ActivityHelper activityHelper, @Nullable SlideConfig slideConfig, @Nullable OnSlideListener slideListener) {
62 | this.helper = activityHelper;
63 | this.curActivity = activity;
64 | this.config = slideConfig;
65 | this.listener = slideListener;
66 | final ViewGroup decorView = getDecorView(curActivity);
67 | if (decorView == null) return null;
68 | final LinearLayout contentView = (LinearLayout) decorView.getChildAt(0);
69 | currentContentView = contentView.findViewById(android.R.id.content);
70 | if (currentContentView.getBackground() == null) {
71 | //延迟设置背景,防止在返回时页面未透明色
72 | //修复在某些手机直接设置背景时背景色为黑色
73 | new Handler(Looper.myLooper()).postDelayed(new Runnable() {
74 | @Override
75 | public void run() {
76 | if (currentContentView == null) return;
77 | currentContentView.setBackground(decorView.getBackground());
78 | }
79 | }, 500);
80 | }
81 | this.preActivity = helper.getPreActivity();
82 | preContentView = getContentView(preActivity);
83 | // if (preContentView == null){
84 | // return null;
85 | // }
86 | decorView.removeViewAt(0);
87 | Drawable preDecorViewDrawable = getDecorViewDrawable(preActivity);
88 | SlideBackLayout slideBackLayout = new SlideBackLayout(curActivity, contentView, preContentView, preDecorViewDrawable, config, new OnInternalStateListener() {
89 | @Override
90 | public void onSlide(float percent) {
91 | if (listener != null) {
92 | listener.onSlide(percent);
93 | }
94 | }
95 |
96 | @Override
97 | public void onOpen() {
98 | if (listener != null) {
99 | listener.onOpen();
100 | }
101 | }
102 |
103 | @Override
104 | public void onClose(Boolean finishActivity) {
105 | // finishActivity为true时关闭页面,为false时不关闭页面,为null时为其他地方关闭页面时调用SlideBackLayout.isComingToFinish的回调
106 | if (listener != null) {
107 | listener.onClose();
108 | }
109 | if ((finishActivity == null || !finishActivity) && listener != null) {
110 | listener.onClose();
111 | }
112 | if (config != null && config.isRotateScreen()) {
113 | if (finishActivity != null && finishActivity) {
114 | // remove了preContentView后布局会重新调整,这时候contentView回到原处,所以要设不可见
115 | contentView.setVisibility(View.INVISIBLE);
116 | }
117 | if (preActivity != null && preContentView != null && preContentView.getParent() != getDecorView(preActivity)) {
118 | // Log.e("TAG", ((SlideBackLayout) preContentView[0].getParent()).getTestName() + "这里把欠人的布局放回到上个Activity");
119 | preContentView.setX(0);
120 | ((ViewGroup) preContentView.getParent()).removeView(preContentView);
121 | getDecorView(preActivity).addView(preContentView, 0);
122 | }
123 | }
124 | if (curActivity == null) return;
125 | curActivity.finish();
126 | // helper.postRemoveActivity(curActivity);
127 | if (preActivity == null || preActivity.isFinishing()) {
128 | return;
129 | }
130 | curActivity.overridePendingTransition(R.anim.sback_anim_activity_none, R.anim.sback_anim_activity_none);
131 | }
132 |
133 | @Override
134 | public void onCheckPreActivity(SlideBackLayout slideBackLayout) {
135 | // Log.e("TAG", "--------------------------------------------------");
136 | // helper.printAllActivity();
137 | // Log.e("TAG", "--------------------------------------------------");
138 | if (helper == null) return;
139 | Activity activity = helper.getPreActivity();
140 | // Log.e("TAG", "SlideBackHelper-120行-onFocus(): " + preActivity[0] + ";" + activity);
141 | if (activity != preActivity) {
142 | // Log.e("TAG", "SlideBackHelper-122行-onFocus(): 上个Activity变了");
143 | preActivity = activity;
144 | if (preActivity == null) return;
145 | preContentView = getContentView(preActivity);
146 | slideBackLayout.updatePreContentView(preContentView);
147 | }
148 | }
149 | });
150 | ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
151 | decorView.addView(slideBackLayout, params);
152 | return slideBackLayout;
153 | }
154 |
155 | /**
156 | * Activity销毁时调用方法
157 | */
158 | public void onDestroy() {
159 | this.helper = null;
160 | this.curActivity = null;
161 | this.preActivity = null;
162 | this.listener = null;
163 | this.config = null;
164 | this.currentContentView = null;
165 | this.preContentView = null;
166 | Log.d("123", "onDestroy: ");
167 | }
168 |
169 | }
170 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/java/com/slideback/SlideConfig.java:
--------------------------------------------------------------------------------
1 | package com.slideback;
2 |
3 | import android.support.annotation.FloatRange;
4 |
5 | /**
6 | * Created by Oubowu on 2016/9/22 23:37.
7 | * 滑动配置
8 | */
9 | public class SlideConfig {
10 |
11 | private boolean mEdgeOnly;
12 | private boolean mLock;
13 |
14 | @FloatRange(from = 0.0, to = 1.0)
15 | private float mEdgePercent;
16 | @FloatRange(from = 0.0, to = 1.0)
17 | private float mSlideOutPercent;
18 |
19 | private float mSlideOutVelocity;
20 |
21 | private boolean mRotateScreen;
22 |
23 | public SlideConfig() {
24 | }
25 |
26 | public boolean isEdgeOnly() {
27 | return mEdgeOnly;
28 | }
29 |
30 | public boolean isLock() {
31 | return mLock;
32 | }
33 |
34 | public float getEdgePercent() {
35 | return mEdgePercent;
36 | }
37 |
38 | public float getSlideOutPercent() {
39 | return mSlideOutPercent;
40 | }
41 |
42 | public float getSlideOutVelocity() {
43 | return mSlideOutVelocity;
44 | }
45 |
46 | /**
47 | * 屏幕是否旋转,针对是否旋转两种方案实现侧滑
48 | *
49 | * @return true为屏幕旋转,false为屏幕不旋转
50 | */
51 | public boolean isRotateScreen() {
52 | return mRotateScreen;
53 | }
54 |
55 | public SlideConfig setEdgeOnly(boolean edgeOnly) {
56 | mEdgeOnly = edgeOnly;
57 | return this;
58 | }
59 |
60 | public SlideConfig setLock(boolean lock) {
61 | mLock = lock;
62 | return this;
63 | }
64 |
65 | public SlideConfig setEdgePercent(float edgePercent) {
66 | mEdgePercent = edgePercent;
67 | return this;
68 | }
69 |
70 | public SlideConfig setSlideOutPercent(float slideOutPercent) {
71 | mSlideOutPercent = slideOutPercent;
72 | return this;
73 | }
74 |
75 | public SlideConfig setSlideOutVelocity(float slideOutVelocity) {
76 | mSlideOutVelocity = slideOutVelocity;
77 | return this;
78 | }
79 |
80 | public SlideConfig setRotateScreen(boolean rotateScreen) {
81 | mRotateScreen = rotateScreen;
82 | return this;
83 | }
84 |
85 |
86 | // public SlideConfig(Builder builder) {
87 | // mEdgeOnly = builder.edgeOnly;
88 | // mLock = builder.lock;
89 | // mEdgePercent = builder.edgePercent;
90 | // mSlideOutPercent = builder.slideOutPercent;
91 | // mSlideOutVelocity = builder.slideOutVelocity;
92 | // mRotateScreen = builder.rotateScreen;
93 | // }
94 |
95 | // public static class Builder {
96 | //
97 | // private boolean edgeOnly = false;
98 | // private boolean lock = false;
99 | //
100 | // @FloatRange(from = 0.0,
101 | // to = 1.0)
102 | // private float edgePercent = 0.4f;
103 | // @FloatRange(from = 0.0,
104 | // to = 1.0)
105 | // private float slideOutPercent = 0.1f;
106 | //
107 | // private float slideOutVelocity = 2000f;
108 | //
109 | // private boolean rotateScreen = false;
110 | //
111 | // public Builder() {
112 | // }
113 | //
114 | // public SlideConfig create() {
115 | // return new SlideConfig(this);
116 | // }
117 | //
118 | // public Builder edgeOnly(boolean edgeOnly) {
119 | // this.edgeOnly = edgeOnly;
120 | // return this;
121 | // }
122 | //
123 | // public Builder lock(boolean lock) {
124 | // this.lock = lock;
125 | // return this;
126 | // }
127 | //
128 | // public Builder slideOutVelocity(float slideOutVelocity) {
129 | // this.slideOutVelocity = slideOutVelocity;
130 | // return this;
131 | // }
132 | //
133 | // public Builder edgePercent(@FloatRange(from = 0.0,
134 | // to = 1.0) float edgePercent) {
135 | // this.edgePercent = edgePercent;
136 | // return this;
137 | // }
138 | //
139 | // public Builder slideOutPercent(@FloatRange(from = 0.0,
140 | // to = 1.0) float slideOutPercent) {
141 | // this.slideOutPercent = slideOutPercent;
142 | // return this;
143 | // }
144 | //
145 | // /**
146 | // * 屏幕是否旋转,针对是否旋转两种方案实现侧滑
147 | // *
148 | // * @return true为屏幕旋转,false为屏幕不旋转
149 | // */
150 | // public Builder rotateScreen(boolean rotateScreen) {
151 | // this.rotateScreen = rotateScreen;
152 | // return this;
153 | // }
154 | //
155 | // }
156 |
157 | }
158 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/java/com/slideback/callbak/OnInternalStateListener.java:
--------------------------------------------------------------------------------
1 | package com.slideback.callbak;
2 |
3 | import android.support.annotation.FloatRange;
4 |
5 | import com.slideback.widget.SlideBackLayout;
6 |
7 | /**
8 | * Created by Oubowu on 2016/9/22 0022 18:22.
9 | */
10 | public interface OnInternalStateListener {
11 |
12 | void onSlide(@FloatRange(from = 0.0,
13 | to = 1.0) float percent);
14 |
15 | void onOpen();
16 |
17 | void onClose(Boolean finishActivity);
18 |
19 | void onCheckPreActivity(SlideBackLayout slideBackLayout);
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/java/com/slideback/callbak/OnSlideListener.java:
--------------------------------------------------------------------------------
1 | package com.slideback.callbak;
2 |
3 | import android.support.annotation.FloatRange;
4 |
5 | /**
6 | * Created by Oubowu on 2016/9/22 0022 18:22.
7 | */
8 | public interface OnSlideListener {
9 |
10 | void onSlide(@FloatRange(from = 0.0,
11 | to = 1.0) float percent);
12 |
13 | void onOpen();
14 |
15 | void onClose();
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/java/com/slideback/callbak/OnSlideListenerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.slideback.callbak;
2 |
3 | import android.support.annotation.FloatRange;
4 |
5 | /**
6 | * Created by Oubowu on 2016/9/23 0:05.
7 | */
8 | public class OnSlideListenerAdapter implements OnSlideListener {
9 | @Override
10 | public void onSlide(@FloatRange(from = 0.0,
11 | to = 1.0) float percent) {
12 | }
13 |
14 | @Override
15 | public void onOpen() {
16 |
17 | }
18 |
19 | @Override
20 | public void onClose() {
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/java/com/slideback/widget/CacheDrawView.java:
--------------------------------------------------------------------------------
1 | package com.slideback.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.view.View;
6 |
7 |
8 | /**
9 | * Created by Oubowu on 2016/9/20 0020 11:19.
10 | *
11 | */
12 | public class CacheDrawView extends View {
13 |
14 | private View mCacheView;
15 |
16 | public CacheDrawView(Context context) {
17 | super(context);
18 | }
19 |
20 | public void drawCacheView(View cacheView) {
21 | mCacheView = cacheView;
22 | invalidate();
23 | }
24 |
25 | @Override
26 | protected void onDraw(Canvas canvas) {
27 | if (mCacheView != null) {
28 | // canvas.drawColor(Color.YELLOW);
29 | mCacheView.draw(canvas);
30 | // Log.e("TAG", "绘制上个Activity的内容视图...");
31 | }
32 | }
33 |
34 | @Override
35 | protected void onDetachedFromWindow() {
36 | super.onDetachedFromWindow();
37 | // Log.e("TAG", "CacheDrawView-37行-onDetachedFromWindow(): ");
38 | mCacheView = null;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/java/com/slideback/widget/ShadowView.java:
--------------------------------------------------------------------------------
1 | package com.slideback.widget;
2 |
3 |
4 | import android.content.Context;
5 | import android.content.res.Configuration;
6 | import android.graphics.Canvas;
7 | import android.graphics.Color;
8 | import android.graphics.LinearGradient;
9 | import android.graphics.Paint;
10 | import android.graphics.RectF;
11 | import android.graphics.Shader;
12 | import android.support.annotation.FloatRange;
13 | import android.view.View;
14 |
15 | /**
16 | * Created by Oubowu on 2016/9/20 0020 11:22.
17 | */
18 | public class ShadowView extends View {
19 |
20 | private LinearGradient mLinearGradient;
21 | private Paint mPaint;
22 | private RectF mRectF;
23 | private float mAlphaPercent = -1;
24 |
25 | public ShadowView(Context context) {
26 | super(context);
27 | mPaint = new Paint();
28 | }
29 |
30 | @Override
31 | protected void onDraw(Canvas canvas) {
32 | if (mAlphaPercent >= 0) {
33 | // 绘制渐变阴影
34 | if (mLinearGradient == null) {
35 | mRectF = new RectF();
36 | int[] colors = {Color.parseColor("#05000000"), Color.parseColor("#22000000"), Color.parseColor("#55000000")};
37 | // 我设置着色器开始的位置为(0,0),结束位置为(getWidth(), 0)表示我的着色器要给整个View在水平方向上渲染
38 | mLinearGradient = new LinearGradient(0, 0, getWidth(), 0, colors, null, Shader.TileMode.REPEAT);
39 | mPaint.setShader(mLinearGradient);
40 | mRectF.set(0, 0, getWidth(), getHeight());
41 | }
42 | mPaint.setAlpha((int) (mAlphaPercent * 255));
43 | canvas.drawRect(mRectF, mPaint);
44 | }
45 | }
46 |
47 | public void redraw(@FloatRange(from = 0.0, to = 1.0) float alphaPercent) {
48 | mAlphaPercent = alphaPercent;
49 | invalidate();
50 | }
51 |
52 | @Override
53 | protected void onConfigurationChanged(Configuration newConfig) {
54 | super.onConfigurationChanged(newConfig);
55 | mLinearGradient = null;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/java/com/slideback/widget/SlideBackLayout.java:
--------------------------------------------------------------------------------
1 | package com.slideback.widget;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.res.Configuration;
6 | import android.graphics.drawable.Drawable;
7 | import android.support.annotation.FloatRange;
8 | import android.support.annotation.NonNull;
9 | import android.support.v4.view.ViewGroupCompat;
10 | import android.support.v4.widget.ViewDragHelper;
11 | import android.util.Log;
12 | import android.view.MotionEvent;
13 | import android.view.VelocityTracker;
14 | import android.view.View;
15 | import android.view.ViewGroup;
16 | import android.widget.FrameLayout;
17 |
18 | import com.slideback.SlideConfig;
19 | import com.slideback.callbak.OnInternalStateListener;
20 |
21 | /**
22 | * Created by Oubowu on 2016/9/22 0022 15:24.
23 | * 滑动控制类
24 | */
25 | public class SlideBackLayout extends FrameLayout {
26 |
27 | private static final int MIN_FLING_VELOCITY = 400;
28 | // private final String mTestName;
29 | private boolean mCheckPreContentView;
30 | private boolean mIsFirstAttachToWindow;
31 | private ViewDragHelper mDragHelper;
32 | private View mContentView;
33 | private CacheDrawView mCacheDrawView;
34 | private ShadowView mShadowView;
35 | private View mPreContentView;
36 | private Drawable mPreDecorViewDrawable;
37 | private int mScreenWidth;
38 | //是否关闭全局侧滑
39 | private boolean mEdgeOnly = false;
40 | //是否关闭侧滑
41 | private boolean mLock = false;
42 | //是否可以滑动
43 | private boolean isSlideBack = true;
44 |
45 | @FloatRange(from = 0.0, to = 1.0)
46 | private float mSlideOutRangePercent = 0.4f;
47 | @FloatRange(from = 0.0, to = 1.0)
48 | private float mEdgeRangePercent = 0.1f;
49 |
50 | private float mSlideOutRange;
51 | private float mEdgeRange;
52 |
53 | private float mSlideOutVelocity;
54 |
55 | private boolean mIsEdgeRangeInside;
56 |
57 | private OnInternalStateListener mOnInternalStateListener;
58 | //按下的点
59 | private float mDownX;
60 | //开始滑动时的点
61 | private float mDownStartX;
62 |
63 | private float mSlidDistantX;
64 |
65 | private boolean mRotateScreen;
66 |
67 | private boolean mCloseFlagForWindowFocus;
68 | private boolean mCloseFlagForDetached;
69 | private boolean mEnableTouchEvent;
70 | //鼠标移动
71 | private VelocityTracker mVelocityTracker;
72 |
73 | public SlideBackLayout(Context context, View contentView, View preContentView, Drawable preDecorViewDrawable, SlideConfig config, @NonNull OnInternalStateListener onInternalStateListener) {
74 | super(context);
75 | mContentView = contentView;
76 | mPreContentView = preContentView;
77 | mPreDecorViewDrawable = preDecorViewDrawable;
78 | mOnInternalStateListener = onInternalStateListener;
79 |
80 | initConfig(config);
81 |
82 | // if (preContentView != null && preContentView instanceof LinearLayout) {
83 | // mTestName = "1号滑动";
84 | // } else {
85 | // mTestName = "2号滑动";
86 | // }
87 | }
88 |
89 | private void initConfig(SlideConfig config) {
90 | if (config == null) {
91 | config = new SlideConfig();
92 | }
93 | mScreenWidth = getResources().getDisplayMetrics().widthPixels;
94 | final float density = getResources().getDisplayMetrics().density;
95 | final float minVel = MIN_FLING_VELOCITY * density;
96 |
97 | ViewGroupCompat.setMotionEventSplittingEnabled(this, false);
98 | SlideLeftCallback slideLeftCallback = new SlideLeftCallback();
99 | mDragHelper = ViewDragHelper.create(this, 1.0f, slideLeftCallback);
100 | // 最小拖动速度
101 | mDragHelper.setMinVelocity(minVel);
102 | mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
103 |
104 | mCacheDrawView = new CacheDrawView(getContext());
105 | mCacheDrawView.setVisibility(INVISIBLE);
106 | addView(mCacheDrawView);
107 |
108 | mShadowView = new ShadowView(getContext());
109 | mShadowView.setVisibility(INVISIBLE);
110 | addView(mShadowView, mScreenWidth / 28, LayoutParams.MATCH_PARENT);
111 |
112 | addView(mContentView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
113 |
114 | mEdgeOnly = config.isEdgeOnly();
115 | mLock = config.isLock();
116 | mRotateScreen = config.isRotateScreen();
117 |
118 | mSlideOutRangePercent = config.getSlideOutPercent();
119 | mEdgeRangePercent = config.getEdgePercent();
120 |
121 | mSlideOutRange = mScreenWidth * mSlideOutRangePercent;
122 | mEdgeRange = mScreenWidth * mEdgeRangePercent;
123 | mSlideOutVelocity = config.getSlideOutVelocity();
124 |
125 | mSlidDistantX = mScreenWidth / 20.0f;
126 |
127 | mContentView.setFitsSystemWindows(false);
128 | // mContentView.getFitsSystemWindows()
129 | if (mRotateScreen) {
130 | mContentView.findViewById(android.R.id.content).setOnClickListener(new OnClickListener() {
131 | @Override
132 | public void onClick(View v) {
133 | // 屏蔽上个内容页的点击事件
134 | }
135 | });
136 | }
137 | }
138 |
139 | @Override
140 | public boolean onInterceptTouchEvent(MotionEvent event) {
141 | if (mLock) {//是否关闭侧滑
142 | return false;
143 | }
144 | mDownStartX = event.getX();
145 | switch (event.getAction()) {
146 | case MotionEvent.ACTION_DOWN:
147 | mDownX = mDownStartX;
148 | isSlideBack = isSlide();
149 | // Log.d("123", "onInterceptTouchEvent: 按下事件");
150 | break;
151 | case MotionEvent.ACTION_MOVE:
152 | // 优化侧滑的逻辑,不要一有稍微的滑动就被ViewDragHelper拦截掉了
153 | if (mDownStartX - mDownX < mSlidDistantX) {
154 | // Log.d("123", "onInterceptTouchEvent: 滑动没有拦截");
155 | return false;
156 | }
157 | // Log.d("123", "onInterceptTouchEvent: 滑动继续执行");
158 | break;
159 | }
160 | if (isSlideBack) {
161 | if (mEdgeOnly) {//是否关闭全局侧滑
162 | mIsEdgeRangeInside = isEdgeRangeInside(mDownStartX);
163 | return mIsEdgeRangeInside && mDragHelper.shouldInterceptTouchEvent(event);
164 | } else {//开启全局侧滑
165 | return mDragHelper.shouldInterceptTouchEvent(event);
166 | }
167 | } else {
168 | // Log.d("123", "onInterceptTouchEvent: 上个页面被销毁:" + event.getAction());
169 | mIsEdgeRangeInside = isEdgeRangeInside(mDownX);
170 | if (MotionEvent.ACTION_MOVE != event.getAction()) {
171 | // Log.d("123", "onInterceptTouchEvent: 不是滑动");
172 | return false;
173 | }
174 | // Log.d("123", "onInterceptTouchEvent: " + mEdgeOnly + ",mDownX:" + isEdgeRangeInside(mDownX));
175 | return !mEdgeOnly || mIsEdgeRangeInside;
176 | }
177 | }
178 |
179 | /**
180 | * 是否在监听滑动范围
181 | */
182 | private boolean isEdgeRangeInside(float x) {
183 | return x <= mEdgeRange;
184 | }
185 |
186 | @Override
187 | public boolean onTouchEvent(MotionEvent event) {
188 | if (mLock) {
189 | return super.onTouchEvent(event);
190 | }
191 | // Log.d("123", "onTouchEvent: 开始监听");
192 | if (mEdgeOnly && !mIsEdgeRangeInside) {
193 | return super.onTouchEvent(event);
194 | }
195 | // Log.d("123", "onTouchEvent: mEnableTouchEvent:" + mEnableTouchEvent);
196 | if (!mEnableTouchEvent) {
197 | return super.onTouchEvent(event);
198 | }
199 | if (mCloseFlagForDetached || mCloseFlagForWindowFocus) {
200 | // 针对快速滑动的时候,页面关闭的时候移除上个页面的时候,布局重新调整,这时候我们把contentView设为invisible,
201 | // 但是还是可以响应DragHelper的处理,所以这里根据页面关闭的标志位不给处理事件了
202 | // Log.e("TAG", mTestName + "都要死了,还处理什么触摸事件!!");
203 | return super.onTouchEvent(event);
204 | }
205 | if (isSlideBack) {
206 | // Log.d("123", "onTouchEvent: 上个页面没有销毁");
207 | mDragHelper.processTouchEvent(event);
208 | } else {
209 | // Log.d("123", "onTouchEvent: 上个页面被销毁");
210 | switch (event.getAction()) {
211 | case MotionEvent.ACTION_POINTER_UP:
212 | case MotionEvent.ACTION_UP:
213 | case MotionEvent.ACTION_CANCEL:
214 | //intunitis表示速率的基本时间单位。unitis值为1的表示是,
215 | // 一毫秒时间单位内运动了多少个像素, unitis值为1000表示一秒(1000毫秒)时间单位内运动了多少个像素
216 | mVelocityTracker.computeCurrentVelocity(1000);
217 | if (getXVelocity() >= mDragHelper.getMinVelocity() * 0.8 || event.getX() - mDownStartX >= mSlideOutRange) {
218 | //关闭页面
219 | mCloseFlagForWindowFocus = true;
220 | mCloseFlagForDetached = true;
221 | mOnInternalStateListener.onClose(true);
222 | }
223 | cancelVelocity();
224 | return true;
225 | default:
226 | addMovement(event);
227 | break;
228 | }
229 | }
230 | return true;
231 | }
232 |
233 | public void addMovement(MotionEvent event) {
234 | if (mVelocityTracker == null) {
235 | mVelocityTracker = VelocityTracker.obtain();
236 | }
237 | mVelocityTracker.addMovement(event);
238 | }
239 |
240 | private float getXVelocity() {
241 | if (mVelocityTracker == null) {
242 | return 0;
243 | }
244 | return mVelocityTracker.getXVelocity();
245 | }
246 |
247 | public void cancelVelocity() {
248 | if (mVelocityTracker != null) {
249 | mVelocityTracker.recycle();
250 | mVelocityTracker = null;
251 | }
252 | }
253 |
254 | private void addPreContentView() {
255 | if (isSlideBack) return;
256 | if (mPreContentView != null && mPreContentView.getParent() != SlideBackLayout.this) {
257 | // Log.e("TAG", mTestName + ": 我要把上个页面的内容页加到我这里啦!");
258 | mPreContentView.setTag("notScreenOrientationChange");
259 | ViewGroup viewGroup = (ViewGroup) mPreContentView.getParent();
260 | if (viewGroup != null)
261 | viewGroup.removeView(mPreContentView);
262 | SlideBackLayout.this.addView(mPreContentView, 0);
263 | mShadowView.setVisibility(VISIBLE);
264 | }
265 | }
266 |
267 | @Override
268 | public void computeScroll() {
269 | if (mDragHelper.continueSettling(true)) {
270 | invalidate();
271 | }
272 | }
273 |
274 | public void isComingToFinish() {
275 | if (mRotateScreen) {
276 | mCloseFlagForDetached = true;
277 | mCloseFlagForWindowFocus = false;
278 | mOnInternalStateListener.onClose(null);
279 | if (mPreContentView != null)
280 | mPreContentView.setX(0);
281 | }
282 | }
283 |
284 | public void updatePreContentView(View contentView) {
285 | mPreContentView = contentView;
286 | mCacheDrawView.drawCacheView(mPreContentView);
287 | }
288 |
289 | private boolean isSlide() {
290 | if (mPreContentView == null) return false;
291 | Context context = mPreContentView.getContext();
292 | if (context == null || !(context instanceof Activity) || ((Activity) context).isFinishing()) {
293 | return false;
294 | }
295 | return true;
296 | }
297 |
298 | private class SlideLeftCallback extends ViewDragHelper.Callback {
299 |
300 | @Override
301 | public boolean tryCaptureView(View child, int pointerId) {
302 | //是否可以移动
303 | return isSlideBack && child == mContentView;
304 | }
305 |
306 | @Override
307 | public int clampViewPositionHorizontal(View child, int left, int dx) {
308 | //分别为即将移动到的位置,比如横向的情况下,我希望只在ViewGroup的内部移动,
309 | //即:最小>=paddingleft,最大<=ViewGroup.getWidth()-paddingright-child.getWidth
310 | return Math.max(Math.min(mScreenWidth, left), 0);
311 | }
312 |
313 | @Override
314 | public int getViewHorizontalDragRange(View child) {
315 | return mScreenWidth;
316 | }
317 |
318 | @Override
319 | public void onViewReleased(View releasedChild, float xvel, float yvel) {
320 | //手指抬起时回调方法
321 | if (!isSlideBack) {
322 | return;
323 | }
324 | if (releasedChild == mContentView) {
325 | if (xvel > mSlideOutVelocity) {
326 | mDragHelper.settleCapturedViewAt(mScreenWidth, 0);
327 | invalidate();
328 | return;
329 | }
330 | if (mContentView.getLeft() < mSlideOutRange) {
331 | mDragHelper.settleCapturedViewAt(0, 0);
332 | } else {
333 | mDragHelper.settleCapturedViewAt(mScreenWidth, 0);
334 | }
335 | invalidate();
336 | }
337 | }
338 |
339 | @Override
340 | public void onViewDragStateChanged(int state) {
341 | if (!isSlideBack) {
342 | return;
343 | }
344 | switch (state) {
345 | case ViewDragHelper.STATE_IDLE:
346 | if (mContentView.getLeft() == 0) {
347 | // 2016/9/22 0022 回到原处
348 | mOnInternalStateListener.onOpen();
349 | } else if (mContentView.getLeft() == mScreenWidth) {
350 | // 2016/9/22 0022 结束Activity
351 | // 这里再绘制一次是因为在屏幕旋转的模式下,remove了preContentView后布局会重新调整
352 | if (mRotateScreen && mCacheDrawView.getVisibility() == INVISIBLE) {
353 | mCacheDrawView.setBackground(mPreDecorViewDrawable);
354 | if (mPreContentView != null)
355 | mCacheDrawView.drawCacheView(mPreContentView);
356 | mCacheDrawView.setVisibility(VISIBLE);
357 | // Log.e("TAG", mTestName + ": 这里再绘制一次是因为在屏幕旋转的模式下,remove了preContentView后布局会重新调整");
358 | mCloseFlagForWindowFocus = true;
359 | mCloseFlagForDetached = true;
360 | // Log.e("TAG", mTestName + ": 滑动到尽头了这个界面要死了,把preContentView给回上个Activity");
361 | // 这里setTag是因为下面的回调会把它移除出当前页面,这时候会触发它的onDetachedFromWindow事件,
362 | // 而它的onDetachedFromWindow实际上是来处理屏幕旋转的,所以设置个tag给它,让它知道是当前界面移除它的,并不是屏幕旋转导致的
363 | if (mPreContentView != null)
364 | mPreContentView.setTag("notScreenOrientationChange");
365 | mOnInternalStateListener.onClose(true);
366 | if (mPreContentView != null)
367 | mPreContentView.postDelayed(new Runnable() {
368 | @Override
369 | public void run() {
370 | mCacheDrawView.setBackground(mPreDecorViewDrawable);
371 | mCacheDrawView.drawCacheView(mPreContentView);
372 | }
373 | }, 10);
374 | } else if (!mRotateScreen) {
375 | mCloseFlagForWindowFocus = true;
376 | mCloseFlagForDetached = true;
377 | mOnInternalStateListener.onClose(true);
378 | }
379 | }
380 | break;
381 | default:
382 | break;
383 | }
384 | }
385 |
386 | @Override
387 | public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
388 | if (!mRotateScreen && mCacheDrawView.getVisibility() == INVISIBLE) {
389 | mCacheDrawView.setBackground(mPreDecorViewDrawable);
390 | if (mPreContentView != null)
391 | mCacheDrawView.drawCacheView(mPreContentView);
392 | mCacheDrawView.setVisibility(VISIBLE);
393 | } else if (mRotateScreen) {
394 | if (!mCheckPreContentView) {
395 | // 在旋转屏幕的模式下,这里的检查很有必要,比如一个滑动activity先旋转了屏幕,然后再返回上个滑动activity的时候,由于屏幕旋转上个activity会重建,步骤是:
396 | // 上个activity会先新建一个activity,再把之前的销毁,所以新建的activity调SlideBackLayout.attach的时候传的上个activity实际上是要删掉的activity
397 | // (因为要删掉的activity的destroy有延时的,还没销毁掉),这就出错了;
398 | // 所以这里还要在当前页面取得焦点的时候回调,去检查下看是不是上个activity改了,改了再重新赋值
399 | mCheckPreContentView = true;
400 | // 只需要检查一次上个Activity是不是变了
401 | // Log.e("TAG","只需要检查一次上个Activity是不是变了");
402 | mOnInternalStateListener.onCheckPreActivity(SlideBackLayout.this);
403 | }
404 | addPreContentView();
405 | }
406 | if (mShadowView.getVisibility() != VISIBLE) {
407 | mShadowView.setVisibility(VISIBLE);
408 | }
409 | final float percent = left * 1.0f / mScreenWidth;
410 | mOnInternalStateListener.onSlide(percent);
411 | if (mRotateScreen) {
412 | // // Log.e("TAG", "滑动上个页面");
413 | if (mPreContentView != null)
414 | mPreContentView.setX(-mScreenWidth / 2 + percent * (mScreenWidth / 2));
415 | } else {
416 | mCacheDrawView.setX(-mScreenWidth / 2 + percent * (mScreenWidth / 2));
417 | }
418 | mShadowView.setX(mContentView.getX() - mShadowView.getWidth());
419 | mShadowView.redraw(1 - percent);
420 | }
421 | }
422 |
423 | public void edgeOnly(boolean edgeOnly) {
424 | mEdgeOnly = edgeOnly;
425 | }
426 |
427 | public boolean isEdgeOnly() {
428 | return mEdgeOnly;
429 | }
430 |
431 | public void lock(boolean lock) {
432 | mLock = lock;
433 | }
434 |
435 | public boolean isLock() {
436 | return mLock;
437 | }
438 |
439 | public void setSlideOutRangePercent(float slideOutRangePercent) {
440 | mSlideOutRangePercent = slideOutRangePercent;
441 | mSlideOutRange = mScreenWidth * mSlideOutRangePercent;
442 | }
443 |
444 | public float getSlideOutRangePercent() {
445 | return mSlideOutRangePercent;
446 | }
447 |
448 | public void setEdgeRangePercent(float edgeRangePercent) {
449 | mEdgeRangePercent = edgeRangePercent;
450 | mEdgeRange = mScreenWidth * mEdgeRangePercent;
451 | }
452 |
453 | public float getEdgeRangePercent() {
454 | return mEdgeRangePercent;
455 | }
456 |
457 | @Override
458 | public void onWindowFocusChanged(boolean hasWindowFocus) {
459 | super.onWindowFocusChanged(hasWindowFocus);
460 | if (hasWindowFocus) {
461 | mEnableTouchEvent = true;
462 | // 当前页面
463 | if (!mIsFirstAttachToWindow) {
464 | mIsFirstAttachToWindow = true;
465 | }
466 | } else {
467 | if (mRotateScreen) {
468 | // 1.跳转到另外一个Activity,例如也是需要滑动的,这时候就需要取当前Activity的contentView,所以这里把preContentView给回上个Activity
469 | if (mCloseFlagForWindowFocus) {
470 | mCloseFlagForWindowFocus = false;
471 | // Log.e("TAG", mTestName + ": onWindowFocusChanged前已经调了关闭");
472 | } else {
473 | // Log.e("TAG", mTestName + ": 跳转到另外一个Activity,取这个Activity的contentView前把preContentView给回上个Activity");
474 | mOnInternalStateListener.onClose(false);
475 | }
476 | }
477 | }
478 | }
479 |
480 | @Override
481 | protected void onDetachedFromWindow() {
482 | super.onDetachedFromWindow();
483 | mEnableTouchEvent = false;
484 | cancelVelocity();
485 | // // Log.e("TAG", "SlideBackLayout-345行-onDetachedFromWindow(): " + this);
486 | if (mRotateScreen) {
487 | // 1.旋转屏幕的时候必调此方法,这里掉onClose目的是把preContentView给回上个Activity
488 | if (mCloseFlagForDetached) {
489 | mCloseFlagForDetached = false;
490 | // Log.e("TAG", mTestName + ": onDetachedFromWindow(): " + "已经调了关闭");
491 | } else {
492 | if (getTag() != null && getTag().equals("notScreenOrientationChange")) {
493 | // 说明是手动删的不关旋转屏幕的事,所以不处理
494 | // Log.e("TAG", mTestName + ":说明是手动删的不关旋转屏幕的事,所以不处理");
495 | setTag(null);
496 | } else {
497 | // Log.e("TAG", mTestName + ":屏幕旋转了,重建界面: 把preContentView给回上个Activity");
498 | mOnInternalStateListener.onClose(false);
499 | }
500 | }
501 | }
502 | }
503 |
504 | @Override
505 | protected void onConfigurationChanged(Configuration newConfig) {
506 | super.onConfigurationChanged(newConfig);
507 | mScreenWidth = getResources().getDisplayMetrics().widthPixels;
508 | // Log.e("TAG", mTestName + ": SlideBackLayout-338行-onConfigurationChanged(): " + mScreenWidth);
509 | ViewGroup.LayoutParams layoutParams = mShadowView.getLayoutParams();
510 | layoutParams.width = mScreenWidth / 28;
511 | layoutParams.height = LayoutParams.MATCH_PARENT;
512 | }
513 |
514 | /**
515 | * 上一个页面被关闭
516 | */
517 | public void setPreContentDestroy() {
518 | mPreContentView = null;
519 | Log.d("123", "上个页面被关闭了");
520 | }
521 |
522 | }
523 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/res/anim/anim_out_none.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
11 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/res/anim/sback_anim_activity_none.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/res/anim/sback_close_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/res/anim/sback_close_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/res/anim/sback_open_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/res/anim/sback_open_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/res/drawable/sliding_back_shadow.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/res/layout/slide_back_default_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/sideBackLibrary/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------