Commit 456ba80d8333a5f9b76c2a55dcec5881ba29c919
1 parent
1496174c
Exists in
master
no message
Showing
166 changed files
with
15196 additions
and
19 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 166 files displayed.
.idea/gradle.xml
.idea/misc.xml
1 | 1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | 2 | <project version="4"> |
3 | + <component name="NullableNotNullManager"> | |
4 | + <option name="myDefaultNullable" value="android.support.annotation.Nullable" /> | |
5 | + <option name="myDefaultNotNull" value="android.support.annotation.NonNull" /> | |
6 | + <option name="myNullables"> | |
7 | + <value> | |
8 | + <list size="4"> | |
9 | + <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" /> | |
10 | + <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" /> | |
11 | + <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" /> | |
12 | + <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" /> | |
13 | + </list> | |
14 | + </value> | |
15 | + </option> | |
16 | + <option name="myNotNulls"> | |
17 | + <value> | |
18 | + <list size="4"> | |
19 | + <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" /> | |
20 | + <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" /> | |
21 | + <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" /> | |
22 | + <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" /> | |
23 | + </list> | |
24 | + </value> | |
25 | + </option> | |
26 | + </component> | |
3 | 27 | <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK"> |
4 | 28 | <output url="file://$PROJECT_DIR$/build/classes" /> |
5 | 29 | </component> | ... | ... |
.idea/modules.xml
... | ... | @@ -4,6 +4,7 @@ |
4 | 4 | <modules> |
5 | 5 | <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" /> |
6 | 6 | <module fileurl="file://$PROJECT_DIR$/expressscanner.iml" filepath="$PROJECT_DIR$/expressscanner.iml" /> |
7 | + <module fileurl="file://$PROJECT_DIR$/mvpsdk/mvpsdk.iml" filepath="$PROJECT_DIR$/mvpsdk/mvpsdk.iml" /> | |
7 | 8 | </modules> |
8 | 9 | </component> |
9 | 10 | </project> |
10 | 11 | \ No newline at end of file | ... | ... |
app/build.gradle
... | ... | @@ -19,10 +19,13 @@ android { |
19 | 19 | } |
20 | 20 | |
21 | 21 | dependencies { |
22 | - implementation fileTree(dir: 'libs', include: ['*.jar']) | |
22 | + implementation fileTree(include: ['*.jar'], dir: 'libs') | |
23 | 23 | implementation 'com.android.support:appcompat-v7:26.1.0' |
24 | 24 | implementation 'com.android.support.constraint:constraint-layout:1.1.0' |
25 | + implementation 'com.android.support:support-v4:26.1.0' | |
25 | 26 | testImplementation 'junit:junit:4.12' |
26 | 27 | androidTestImplementation 'com.android.support.test:runner:1.0.1' |
27 | 28 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' |
29 | + implementation project(':mvpsdk') | |
30 | + implementation files('libs/zkcsdk.jar') | |
28 | 31 | } | ... | ... |
No preview for this file type
app/src/main/AndroidManifest.xml
1 | 1 | <?xml version="1.0" encoding="utf-8"?> |
2 | 2 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
3 | - package="com.shunzhi.expressscanner" > | |
3 | + package="com.shunzhi.expressscanner"> | |
4 | + | |
5 | + <uses-permission android:name="android.permission.INTERNET" /> | |
4 | 6 | |
5 | 7 | <application |
8 | + android:name=".AppContext" | |
6 | 9 | android:allowBackup="true" |
7 | 10 | android:icon="@mipmap/ic_launcher" |
8 | 11 | android:label="@string/app_name" |
9 | 12 | android:roundIcon="@mipmap/ic_launcher_round" |
10 | 13 | android:supportsRtl="true" |
11 | - android:theme="@style/AppTheme" > | |
12 | - <activity android:name=".MainActivity" > | |
14 | + android:theme="@style/AppTheme"> | |
15 | + <activity | |
16 | + android:name=".MainActivity" | |
17 | + android:theme="@style/Theme.AppCompat.Light.NoActionBar"> | |
13 | 18 | <intent-filter> |
14 | 19 | <action android:name="android.intent.action.MAIN" /> |
15 | 20 | |
16 | 21 | <category android:name="android.intent.category.LAUNCHER" /> |
17 | 22 | </intent-filter> |
18 | 23 | </activity> |
24 | + <activity | |
25 | + android:name=".base.BaseActivity" | |
26 | + android:label="@string/title_activity_base" | |
27 | + android:theme="@style/AppTheme.NoActionBar"></activity> | |
19 | 28 | </application> |
20 | 29 | |
21 | 30 | </manifest> |
22 | 31 | \ No newline at end of file | ... | ... |
app/src/main/java/com/shunzhi/expressscanner/AppConfig.java
0 → 100644
... | ... | @@ -0,0 +1,57 @@ |
1 | +package com.shunzhi.expressscanner; | |
2 | + | |
3 | +import android.content.Context; | |
4 | +import android.content.SharedPreferences; | |
5 | +import android.preference.PreferenceManager; | |
6 | +import android.text.TextUtils; | |
7 | + | |
8 | +/** | |
9 | + * Created by ToaHanDong on 2018/4/24. | |
10 | + */ | |
11 | + | |
12 | +public class AppConfig { | |
13 | + | |
14 | +// public static String BASE_URL="http://ecampus.zjyzzx.net/"; | |
15 | + | |
16 | + public static String BASE_URL="http://60.190.202.57:1000/"; | |
17 | + | |
18 | + public static String LOGIN_NAME="15305755683"; | |
19 | + public static String LOGIN_PWD="755683"; | |
20 | + | |
21 | + public static String ACCESS_TOKEN = "access_token"; | |
22 | + public static final String OPEN_SCAN = "open_scan"; | |
23 | + public static String CURRENT_USERID = "current_userid"; | |
24 | + public static String SCHOOL_ID="school_id"; | |
25 | + | |
26 | + private static AppConfig appConfig = null; | |
27 | + public static AppConfig getAppConfig() { | |
28 | + if (appConfig == null) { | |
29 | + appConfig = new AppConfig(); | |
30 | + } | |
31 | + return appConfig; | |
32 | + } | |
33 | + | |
34 | + //得到保存的值 | |
35 | + public String get(String key) { | |
36 | + return getSharedPreferences(AppContext.getContext()).getString(key, null); | |
37 | + } | |
38 | + | |
39 | + private SharedPreferences getSharedPreferences(Context context) { | |
40 | + return PreferenceManager.getDefaultSharedPreferences(context); | |
41 | + } | |
42 | + | |
43 | + //保存键值对 | |
44 | + public void set(String key, String value) { | |
45 | + SharedPreferences.Editor editor = getSharedPreferences(AppContext.getContext()).edit(); | |
46 | + if (TextUtils.isEmpty(value)) { | |
47 | + editor.putString(key, value); | |
48 | + } else { | |
49 | + editor.putString(key, value.trim()); | |
50 | + } | |
51 | + editor.commit(); | |
52 | + } | |
53 | + | |
54 | + public boolean getBoolean(String openScan) { | |
55 | + return true; | |
56 | + } | |
57 | +} | ... | ... |
app/src/main/java/com/shunzhi/expressscanner/AppContext.java
0 → 100644
... | ... | @@ -0,0 +1,19 @@ |
1 | +package com.shunzhi.expressscanner; | |
2 | + | |
3 | +import com.share.mvpsdk.global.GlobalApplication; | |
4 | +import com.share.mvpsdk.helper.RetrofitCreateHelper; | |
5 | + | |
6 | +/** | |
7 | + * Created by ToaHanDong on 2018/4/24. | |
8 | + */ | |
9 | + | |
10 | +public class AppContext extends GlobalApplication { | |
11 | + | |
12 | + @Override | |
13 | + public void onCreate() { | |
14 | + super.onCreate(); | |
15 | + | |
16 | + RetrofitCreateHelper.getInstance().setAuthorization(AppConfig.getAppConfig().get(AppConfig.ACCESS_TOKEN)); | |
17 | + | |
18 | + } | |
19 | +} | ... | ... |
app/src/main/java/com/shunzhi/expressscanner/MainActivity.java
1 | 1 | package com.shunzhi.expressscanner; |
2 | 2 | |
3 | +import android.annotation.SuppressLint; | |
4 | +import android.content.Context; | |
5 | +import android.media.MediaPlayer; | |
6 | +import android.os.Message; | |
7 | +import android.os.RemoteException; | |
8 | +import android.os.Vibrator; | |
9 | +import android.support.v4.app.FragmentTransaction; | |
3 | 10 | import android.support.v7.app.AppCompatActivity; |
4 | 11 | import android.os.Bundle; |
12 | +import android.widget.FrameLayout; | |
13 | +import android.widget.Toast; | |
5 | 14 | |
6 | -public class MainActivity extends AppCompatActivity { | |
15 | +import com.share.mvpsdk.base.activity.BaseCompatActivity; | |
16 | +import com.shunzhi.expressscanner.base.BaseActivity; | |
17 | +import com.shunzhi.expressscanner.fragment.MainFragment; | |
18 | +import com.smartdevice.aidl.ICallBack; | |
19 | +import com.smartdevice.aidl.IZKCService; | |
20 | +import com.zkc.baseLibrary.MessageType; | |
21 | + | |
22 | +public class MainActivity extends BaseCompatActivity { | |
23 | + | |
24 | + FrameLayout frame; | |
25 | + | |
26 | + FragmentTransaction fragmentTransaction = null; | |
27 | + | |
28 | + MainFragment mainFragment; | |
29 | + | |
30 | + @Override | |
31 | + protected void initView(Bundle savedInstanceState) { | |
32 | + | |
33 | + frame = findViewById(R.id.frame); | |
34 | + fragmentTransaction = getSupportFragmentManager().beginTransaction(); | |
35 | + mainFragment = new MainFragment(); | |
36 | + fragmentTransaction.add(R.id.frame, mainFragment) | |
37 | + .show(mainFragment).commit(); | |
38 | + | |
39 | + } | |
7 | 40 | |
8 | 41 | @Override |
9 | - protected void onCreate(Bundle savedInstanceState) { | |
10 | - super.onCreate(savedInstanceState); | |
11 | - setContentView(R.layout.activity_main); | |
42 | + protected int getLayoutId() { | |
43 | + return R.layout.activity_main; | |
12 | 44 | } |
13 | 45 | } | ... | ... |
app/src/main/java/com/shunzhi/expressscanner/api/MainApi.java
0 → 100644
... | ... | @@ -0,0 +1,42 @@ |
1 | +package com.shunzhi.expressscanner.api; | |
2 | + | |
3 | +import com.google.gson.JsonObject; | |
4 | + | |
5 | +import io.reactivex.Observable; | |
6 | +import retrofit2.http.Field; | |
7 | +import retrofit2.http.FormUrlEncoded; | |
8 | +import retrofit2.http.GET; | |
9 | +import retrofit2.http.POST; | |
10 | +import retrofit2.http.Query; | |
11 | + | |
12 | +/** | |
13 | + * Created by ToaHanDong on 2018/4/24. | |
14 | + */ | |
15 | + | |
16 | +public interface MainApi { | |
17 | + | |
18 | + @FormUrlEncoded | |
19 | + @POST("Token") | |
20 | + Observable<JsonObject> login(@Field("grant_type") String grant_type, @Field("username") String username | |
21 | + , @Field("password") String password); | |
22 | + | |
23 | + @GET("api/NewAssets/IsExpressReceive") | |
24 | + Observable<JsonObject> getExpressInfo(@Query("ExpressNumber") String expressCode,@Query("schoolid") String schoolId); | |
25 | + | |
26 | + @POST("api/Account/CurrentInfo") | |
27 | + Observable<JsonObject> getCurrentInfo(); | |
28 | + | |
29 | + @GET("api/NewAssets/SearchExpressPhone") | |
30 | + Observable<JsonObject> SearchExpressPhone(@Query("moilb") String moilb); | |
31 | + | |
32 | + @GET("api/NewAssets/SearchNameByPhone") | |
33 | + Observable<JsonObject> SearchNameByPhone(@Query("moilb") String moilb); | |
34 | + | |
35 | + @GET("api/NewAssets/InsertExpress") | |
36 | + Observable<JsonObject> InsertExpress(@Query("ExpressNumber") String ExpressNumber,@Query("MoilePhone") String MoilePhone, | |
37 | + @Query("UserName") String UserName,@Query("schoolId") String schoolId); | |
38 | + | |
39 | + @GET("api/NewAssets/UpdateIsReceive") | |
40 | + Observable<JsonObject> UpdateIsReceive(@Query("ExpressNumber") String ExpressNumber,@Query("schoolId") String schoolId); | |
41 | + | |
42 | +} | ... | ... |
app/src/main/java/com/shunzhi/expressscanner/base/BaseActivity.java
0 → 100644
... | ... | @@ -0,0 +1,77 @@ |
1 | +package com.shunzhi.expressscanner.base; | |
2 | + | |
3 | +import android.content.Context; | |
4 | +import android.os.Bundle; | |
5 | +import android.os.Handler; | |
6 | +import android.os.Message; | |
7 | +import android.support.design.widget.FloatingActionButton; | |
8 | +import android.support.design.widget.Snackbar; | |
9 | +import android.support.v7.app.AppCompatActivity; | |
10 | +import android.support.v7.widget.Toolbar; | |
11 | +import android.view.View; | |
12 | +import android.view.inputmethod.InputMethodManager; | |
13 | + | |
14 | +import com.share.mvpsdk.base.activity.BaseCompatActivity; | |
15 | +import com.shunzhi.expressscanner.R; | |
16 | +import com.shunzhi.expressscanner.common.MessageCenter; | |
17 | +import com.smartdevice.aidl.IZKCService; | |
18 | +import com.zkc.baseLibrary.ZkcManager; | |
19 | + | |
20 | +public abstract class BaseActivity extends BaseCompatActivity { | |
21 | + public static int DEVICE_MODEL = 0; | |
22 | + public Handler mhanlder; | |
23 | + public IZKCService mIzkcService = null; | |
24 | + | |
25 | + @Override | |
26 | + protected void onCreate(Bundle savedInstanceState) { | |
27 | + super.onCreate(savedInstanceState); | |
28 | + setContentView(getLayoutId()); | |
29 | + MessageCenter.getInstance().addHandler(getHandler()); | |
30 | + initView(savedInstanceState); | |
31 | + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); | |
32 | + imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS); | |
33 | + //创建接口管理者对象 create the object of interface manager | |
34 | + ZkcManager.getInstance().onCreate(this, mhanlder); | |
35 | +// Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); | |
36 | +// setSupportActionBar(toolbar); | |
37 | +// | |
38 | +// FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); | |
39 | +// fab.setOnClickListener(new View.OnClickListener() { | |
40 | +// @Override | |
41 | +// public void onClick(View view) { | |
42 | +// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) | |
43 | +// .setAction("Action", null).show(); | |
44 | +// } | |
45 | +// }); | |
46 | + } | |
47 | + | |
48 | + protected void handleStateMessage(Message message) { | |
49 | + } | |
50 | + | |
51 | + /** | |
52 | + * handler | |
53 | + */ | |
54 | + protected Handler getHandler() { | |
55 | + if (mhanlder == null) { | |
56 | + mhanlder = new Handler() { | |
57 | + public void handleMessage(Message msg) { | |
58 | + handleStateMessage(msg); | |
59 | + } | |
60 | + }; | |
61 | + } | |
62 | + return mhanlder; | |
63 | + } | |
64 | + | |
65 | + protected void sendMessage(int what, Object obj) { | |
66 | + Message message = new Message(); | |
67 | + message.what = what; | |
68 | + message.obj = obj; | |
69 | + getHandler().sendMessage(message); | |
70 | + } | |
71 | + | |
72 | + protected abstract void initView(Bundle savedInstanceState); | |
73 | + | |
74 | + protected abstract int getLayoutId(); | |
75 | + | |
76 | + | |
77 | +} | ... | ... |
app/src/main/java/com/shunzhi/expressscanner/bean/ExpressBean.java
0 → 100644
... | ... | @@ -0,0 +1,26 @@ |
1 | +package com.shunzhi.expressscanner.bean; | |
2 | + | |
3 | +/** | |
4 | + * Created by ToaHanDong on 2018/4/24. | |
5 | + */ | |
6 | + | |
7 | +public class ExpressBean { | |
8 | + | |
9 | + public String expressCode; | |
10 | + | |
11 | + public String teacherName; | |
12 | + | |
13 | + public String teacherNum; | |
14 | + | |
15 | + public int state;//0:未领取 1:已领取 2:未录入 | |
16 | + | |
17 | + @Override | |
18 | + public String toString() { | |
19 | + return "ExpressBean{" + | |
20 | + "expressCode='" + expressCode + '\'' + | |
21 | + ", teacherName='" + teacherName + '\'' + | |
22 | + ", teacherNum='" + teacherNum + '\'' + | |
23 | + ", state=" + state + | |
24 | + '}'; | |
25 | + } | |
26 | +} | ... | ... |
app/src/main/java/com/shunzhi/expressscanner/common/MessageCenter.java
0 → 100644
... | ... | @@ -0,0 +1,60 @@ |
1 | +package com.shunzhi.expressscanner.common; | |
2 | + | |
3 | +import android.os.Handler; | |
4 | +import android.os.Message; | |
5 | + | |
6 | +import java.util.List; | |
7 | +import java.util.Vector; | |
8 | + | |
9 | +public class MessageCenter { | |
10 | + | |
11 | + private List<Handler> mHandlerList = new Vector<Handler>(); | |
12 | + private static MessageCenter CENTER = null; | |
13 | + | |
14 | + private MessageCenter() { | |
15 | + | |
16 | + } | |
17 | + | |
18 | + public static MessageCenter getInstance() { | |
19 | + if (CENTER == null) { | |
20 | + CENTER = new MessageCenter(); | |
21 | + } | |
22 | + return CENTER; | |
23 | + } | |
24 | + | |
25 | + public synchronized void addHandler(Handler handler) { | |
26 | + mHandlerList.add(handler); | |
27 | + } | |
28 | + | |
29 | + public synchronized void removeHandler(Handler handler) { | |
30 | + mHandlerList.remove(handler); | |
31 | + } | |
32 | + | |
33 | + public synchronized void sendMessage(int what, Object obj) { | |
34 | + Message message = new Message(); | |
35 | + message.obj = obj; | |
36 | + message.what = what; | |
37 | + sendMessage(message); | |
38 | + } | |
39 | + | |
40 | + public synchronized void sendMessageWithPre(int what, Object obj, int arg1) { | |
41 | + Message message = new Message(); | |
42 | + message.obj = obj; | |
43 | + message.arg1 = arg1; | |
44 | + message.what = what; | |
45 | + sendMessage(message); | |
46 | + } | |
47 | + | |
48 | + public synchronized void sendMessage(Message message) { | |
49 | + for (Handler handler : mHandlerList) { | |
50 | + handler.sendMessage(Message.obtain(message)); | |
51 | + } | |
52 | + } | |
53 | + | |
54 | + public synchronized void sendEmptyMessage(int what) { | |
55 | + for (Handler handler : mHandlerList) { | |
56 | + handler.sendEmptyMessage(what); | |
57 | + } | |
58 | + } | |
59 | + | |
60 | +} | ... | ... |
app/src/main/java/com/shunzhi/expressscanner/contract/MainContract.java
0 → 100644
... | ... | @@ -0,0 +1,70 @@ |
1 | +package com.shunzhi.expressscanner.contract; | |
2 | + | |
3 | +import com.google.gson.JsonObject; | |
4 | +import com.share.mvpsdk.base.BasePresenter; | |
5 | +import com.share.mvpsdk.base.IBaseFragment; | |
6 | +import com.share.mvpsdk.base.IBaseModel; | |
7 | +import com.share.mvpsdk.base.IBaseView; | |
8 | +import com.shunzhi.expressscanner.bean.ExpressBean; | |
9 | + | |
10 | +import java.util.List; | |
11 | + | |
12 | +import io.reactivex.Observable; | |
13 | + | |
14 | +/** | |
15 | + * Created by ToaHanDong on 2018/4/24. | |
16 | + */ | |
17 | + | |
18 | +public interface MainContract { | |
19 | + | |
20 | + abstract class MainPresenter extends BasePresenter<IMainModel,IMainView>{ | |
21 | + | |
22 | + public abstract void login(String loginName,String loginPwd); | |
23 | + | |
24 | + public abstract void getExpressInfo(String expressCode); | |
25 | + | |
26 | + public abstract void getTeacherName(String tel); | |
27 | + | |
28 | + public abstract void upExpressInfo(ExpressBean expressBean); | |
29 | + | |
30 | + public abstract void SearchExpressPhone(String mobile); | |
31 | + | |
32 | + public abstract void UpdateIsReceive(String ExpressNumber,String schoolId); | |
33 | + | |
34 | + } | |
35 | + | |
36 | + | |
37 | + interface IMainModel extends IBaseModel{ | |
38 | + | |
39 | + Observable<JsonObject> getTeacherName(String tel); | |
40 | + | |
41 | + Observable<JsonObject> getExpressInfo(String expressCode,String schoolId); | |
42 | + | |
43 | + Observable<JsonObject> login(String logName,String logPwd); | |
44 | + | |
45 | + Observable<JsonObject> upExpressInfo(ExpressBean expressBean); | |
46 | + | |
47 | + Observable<JsonObject> getCurrentInfo(); | |
48 | + | |
49 | + Observable<JsonObject> SearchExpressPhone(String mobile); | |
50 | + | |
51 | + Observable<JsonObject> UpdateIsReceive(String ExpressNumber,String schoolId); | |
52 | + | |
53 | + } | |
54 | + | |
55 | + interface IMainView extends IBaseFragment{ | |
56 | + | |
57 | + | |
58 | + void showTeacherName(String name); | |
59 | + | |
60 | + void showExpressInfo(ExpressBean expressBean); | |
61 | + | |
62 | + void showExpressInfoSuccess(boolean isSuccess); | |
63 | + | |
64 | + void showSearchModel(List<String> stringList); | |
65 | + | |
66 | + void showUpdateIsReceive(boolean isUpdate); | |
67 | + } | |
68 | + | |
69 | + | |
70 | +} | ... | ... |
app/src/main/java/com/shunzhi/expressscanner/fragment/MainFragment.java
0 → 100644
... | ... | @@ -0,0 +1,463 @@ |
1 | +package com.shunzhi.expressscanner.fragment; | |
2 | + | |
3 | +import android.annotation.SuppressLint; | |
4 | +import android.content.Context; | |
5 | +import android.graphics.drawable.BitmapDrawable; | |
6 | +import android.media.MediaPlayer; | |
7 | +import android.os.Bundle; | |
8 | +import android.os.Handler; | |
9 | +import android.os.Message; | |
10 | +import android.os.RemoteException; | |
11 | +import android.os.Vibrator; | |
12 | +import android.support.annotation.NonNull; | |
13 | +import android.support.annotation.Nullable; | |
14 | +import android.support.v7.widget.LinearLayoutManager; | |
15 | +import android.support.v7.widget.RecyclerView; | |
16 | +import android.text.Editable; | |
17 | +import android.text.TextWatcher; | |
18 | +import android.view.LayoutInflater; | |
19 | +import android.view.View; | |
20 | +import android.view.ViewGroup; | |
21 | +import android.view.WindowManager; | |
22 | +import android.widget.Button; | |
23 | +import android.widget.EditText; | |
24 | +import android.widget.LinearLayout; | |
25 | +import android.widget.PopupWindow; | |
26 | +import android.widget.TextView; | |
27 | + | |
28 | +import com.share.mvpsdk.base.BasePresenter; | |
29 | +import com.share.mvpsdk.base.adapter.BaseRecyclerViewAdapter; | |
30 | +import com.share.mvpsdk.base.adapter.BaseRecyclerViewHolder; | |
31 | +import com.share.mvpsdk.base.adapter.OnItemClickListener; | |
32 | +import com.share.mvpsdk.base.fragment.BaseMVPCompatFragment; | |
33 | +import com.share.mvpsdk.utils.NetworkConnectionUtils; | |
34 | +import com.share.mvpsdk.utils.StringUtils; | |
35 | +import com.share.mvpsdk.utils.ToastUtils; | |
36 | +import com.shunzhi.expressscanner.AppConfig; | |
37 | +import com.shunzhi.expressscanner.R; | |
38 | +import com.shunzhi.expressscanner.bean.ExpressBean; | |
39 | +import com.shunzhi.expressscanner.contract.MainContract; | |
40 | +import com.shunzhi.expressscanner.present.MainPresenter; | |
41 | +import com.smartdevice.aidl.ICallBack; | |
42 | +import com.smartdevice.aidl.IZKCService; | |
43 | +import com.zkc.baseLibrary.MessageType; | |
44 | +import com.zkc.baseLibrary.ZkcManager; | |
45 | + | |
46 | +import java.util.List; | |
47 | + | |
48 | +/** | |
49 | + */ | |
50 | +public class MainFragment extends BaseMVPCompatFragment<MainContract.MainPresenter, MainContract.IMainModel> implements MainContract.IMainView | |
51 | + , View.OnClickListener { | |
52 | + | |
53 | + public MainFragment newInstance() { | |
54 | + MainFragment mainFragment = new MainFragment(); | |
55 | + return mainFragment; | |
56 | + } | |
57 | + | |
58 | + public final int INSERT_SUCCESS = 24; | |
59 | + | |
60 | + EditText etExpressCode, etTel, etName; | |
61 | + | |
62 | + Button tvCommint, tvCancle; | |
63 | + | |
64 | + TextView tvTips; | |
65 | + | |
66 | + public IZKCService mIzkcService = null; | |
67 | + | |
68 | + MediaPlayer player; | |
69 | + | |
70 | + Vibrator vibrator; | |
71 | + | |
72 | + public String text = ""; | |
73 | + | |
74 | + MyPopu myPopu = null; | |
75 | + | |
76 | + LinearLayout layout_tel, layout_name, layout_express; | |
77 | + | |
78 | + @Override | |
79 | + public int getLayoutId() { | |
80 | + return R.layout.fragment_main; | |
81 | + } | |
82 | + | |
83 | + ICallBack.Stub mCallback = new ICallBack.Stub() { | |
84 | + | |
85 | + @SuppressLint("MissingPermission") | |
86 | + @Override | |
87 | + public void onReturnValue(byte[] buffer, int size) | |
88 | + throws RemoteException { | |
89 | + String codeStr = new String(buffer, 0, size); | |
90 | + text = codeStr; | |
91 | + player.start(); | |
92 | +// vibrator.vibrate(100); | |
93 | + Message message = mhanlder.obtainMessage(); | |
94 | + message.what = MessageType.BaiscMessage.SCAN_RESULT_GET_SUCCESS; | |
95 | + message.obj = text; | |
96 | + mhanlder.sendMessage(message); | |
97 | + } | |
98 | + }; | |
99 | + | |
100 | + @Override | |
101 | + public void initUI(View view, @Nullable Bundle savedInstanceState) { | |
102 | + mPresenter.login(AppConfig.LOGIN_NAME, AppConfig.LOGIN_PWD); | |
103 | + | |
104 | + etExpressCode = view.findViewById(R.id.etExpressCode); | |
105 | + etTel = view.findViewById(R.id.etTel); | |
106 | + etName = view.findViewById(R.id.etName); | |
107 | + tvCommint = view.findViewById(R.id.tvCommint); | |
108 | + tvCancle = view.findViewById(R.id.tvCancle); | |
109 | + tvTips = view.findViewById(R.id.tvTips); | |
110 | + layout_tel = view.findViewById(R.id.layout_tel); | |
111 | + layout_name = view.findViewById(R.id.layout_name); | |
112 | + layout_express = view.findViewById(R.id.layout_express); | |
113 | + | |
114 | + tvCommint.setOnClickListener(this); | |
115 | + tvCancle.setOnClickListener(this); | |
116 | + player = MediaPlayer.create(getContext(), R.raw.scan); | |
117 | + vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE); | |
118 | + initZkc(); | |
119 | + if (!NetworkConnectionUtils.isConnected(getContext())){ | |
120 | + ToastUtils.showToast("请连接网络"); | |
121 | + tvTips.setText("网络已断开,请连接网络"); | |
122 | + } | |
123 | + etTel.addTextChangedListener(new TextWatcher() { | |
124 | + @Override | |
125 | + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { | |
126 | + | |
127 | + } | |
128 | + | |
129 | + @Override | |
130 | + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { | |
131 | + | |
132 | + } | |
133 | + | |
134 | + @Override | |
135 | + public void afterTextChanged(Editable editable) { | |
136 | + if (editable.length() >= 3 && tvCommint.getText().toString().equals("确定录入")) | |
137 | + mPresenter.SearchExpressPhone(editable.toString()); | |
138 | + } | |
139 | + }); | |
140 | + } | |
141 | + | |
142 | + private void initZkc() { | |
143 | + | |
144 | + ZkcManager.getInstance().onCreate(getActivity(), mhanlder); | |
145 | + | |
146 | + } | |
147 | + | |
148 | + @NonNull | |
149 | + @Override | |
150 | + public BasePresenter initPresenter() { | |
151 | + return new MainPresenter(); | |
152 | + } | |
153 | + | |
154 | + /** | |
155 | + * 扫描快递后,显示快递的状态 | |
156 | + * | |
157 | + * @param expressBean | |
158 | + */ | |
159 | + @Override | |
160 | + public void showExpressInfo(ExpressBean expressBean) { | |
161 | + | |
162 | + etExpressCode.setText(text); | |
163 | + switch (expressBean.state) { | |
164 | + case 0://未领取 | |
165 | + noImport(expressBean); | |
166 | + break; | |
167 | + case 1://已领取 | |
168 | + hasGetExpress(expressBean); | |
169 | + break; | |
170 | + case 2://未录入 | |
171 | + insertExpress(); | |
172 | + break; | |
173 | + } | |
174 | + | |
175 | + } | |
176 | + | |
177 | + /** | |
178 | + * 显示教师名字 | |
179 | + * | |
180 | + * @param name | |
181 | + */ | |
182 | + @Override | |
183 | + public void showTeacherName(String name) { | |
184 | + if (null != myPopu) myPopu.dismiss(); | |
185 | + etName.setText(name); | |
186 | + tvCommint.setText("确定录入"); | |
187 | + tvTips.setText("提示: 录入快递信息"); | |
188 | + tvCancle.setVisibility(View.VISIBLE); | |
189 | + etExpressCode.setVisibility(View.VISIBLE); | |
190 | + etName.setFocusable(false); | |
191 | + etTel.setFocusable(false); | |
192 | + etExpressCode.setFocusable(false); | |
193 | + } | |
194 | + | |
195 | + //显示快递录入是否成功 | |
196 | + @Override | |
197 | + public void showExpressInfoSuccess(boolean isSuccess) { | |
198 | + if (isSuccess) { | |
199 | + tvTips.setText("录入成功"); | |
200 | + ToastUtils.showToast("录入成功"); | |
201 | + mhanlder.sendEmptyMessageDelayed(INSERT_SUCCESS, 3000); | |
202 | + } | |
203 | + } | |
204 | + | |
205 | + /** | |
206 | + * 模糊查询的手机号 | |
207 | + * | |
208 | + * @param stringList | |
209 | + */ | |
210 | + @Override | |
211 | + public void showSearchModel(List<String> stringList) { | |
212 | + if (null == myPopu) myPopu = new MyPopu(); | |
213 | + myPopu.showAsDropDown(etTel); | |
214 | + myPopu.showDatas(stringList); | |
215 | + //焦点还是要在手机号输入框 | |
216 | + etTel.setFocusable(true); | |
217 | + } | |
218 | + | |
219 | + //显示快递是否领取成功 | |
220 | + @Override | |
221 | + public void showUpdateIsReceive(boolean isUpdate) { | |
222 | + if (isUpdate) { | |
223 | + ToastUtils.showToast("领取成功"); | |
224 | + mhanlder.sendEmptyMessageDelayed(INSERT_SUCCESS, 3000); | |
225 | + } | |
226 | + } | |
227 | + | |
228 | + @Override | |
229 | + public void onClick(View view) { | |
230 | + switch (view.getId()) { | |
231 | + case R.id.tvCommint: | |
232 | + String commintText = tvCommint.getText().toString(); | |
233 | + //录入快递 | |
234 | + if (commintText.equals("确定录入")) { | |
235 | + | |
236 | + if (!StringUtils.isPhoneNumberValid(etTel.getText().toString())) { | |
237 | + ToastUtils.showToast("请输入合法的手机号"); | |
238 | + return; | |
239 | + } | |
240 | + ExpressBean expressBean = new ExpressBean(); | |
241 | + expressBean.expressCode = etExpressCode.getText().toString(); | |
242 | + expressBean.teacherNum = etTel.getText().toString(); | |
243 | + expressBean.teacherName = etName.getText().toString(); | |
244 | + mPresenter.upExpressInfo(expressBean); | |
245 | + | |
246 | + } else if (commintText.equals("确定并扫描快递")) { | |
247 | + | |
248 | + try { | |
249 | + mIzkcService.scan(); | |
250 | + } catch (RemoteException e) { | |
251 | + e.printStackTrace(); | |
252 | + } | |
253 | + | |
254 | + } else if (commintText.equals("领取")) { | |
255 | + mPresenter.UpdateIsReceive(etExpressCode.getText().toString(), AppConfig.getAppConfig().get(AppConfig.SCHOOL_ID)); | |
256 | + } else if (commintText.equals("确定")) { | |
257 | + showExpress(); | |
258 | + } | |
259 | + break; | |
260 | + case R.id.tvCancle: | |
261 | + showExpress(); | |
262 | + break; | |
263 | + } | |
264 | + } | |
265 | + | |
266 | + //显示扫描界面 | |
267 | + private void showExpress() { | |
268 | + layout_express.setVisibility(View.VISIBLE); | |
269 | + layout_name.setVisibility(View.INVISIBLE); | |
270 | + layout_tel.setVisibility(View.INVISIBLE); | |
271 | + tvCancle.setVisibility(View.GONE); | |
272 | + etExpressCode.setFocusable(true); | |
273 | + etName.setFocusable(true); | |
274 | + etTel.setFocusable(true); | |
275 | + etExpressCode.setFocusableInTouchMode(true); | |
276 | + etName.setFocusableInTouchMode(true); | |
277 | + etTel.setFocusableInTouchMode(true); | |
278 | + tvCommint.setText("确定并扫描快递"); | |
279 | + etExpressCode.setText(""); | |
280 | + etTel.setText(""); | |
281 | + etName.setText(""); | |
282 | + etExpressCode.setBackground(getResources().getDrawable(R.drawable.shape_edit)); | |
283 | + tvTips.setText("点击扫描快递按钮扫描快递"); | |
284 | + } | |
285 | + | |
286 | + /** | |
287 | + * 已录入 | |
288 | + * | |
289 | + * @param expressBean | |
290 | + */ | |
291 | + private void noImport(ExpressBean expressBean) { | |
292 | + showContents(expressBean); | |
293 | + tvCommint.setText("领取"); | |
294 | + tvTips.setText("快递未领取,点击领取按钮可领取"); | |
295 | + } | |
296 | + | |
297 | + /** | |
298 | + * 录入快递 | |
299 | + */ | |
300 | + private void insertExpress() { | |
301 | + layout_express.setVisibility(View.VISIBLE); | |
302 | + layout_name.setVisibility(View.VISIBLE); | |
303 | + layout_tel.setVisibility(View.VISIBLE); | |
304 | + tvCancle.setVisibility(View.VISIBLE); | |
305 | + etExpressCode.setBackground(getResources().getDrawable(R.drawable.shape_edit)); | |
306 | + etName.setBackground(getResources().getDrawable(R.drawable.shape_edit)); | |
307 | + etTel.setBackground(getResources().getDrawable(R.drawable.shape_edit)); | |
308 | + tvCommint.setText("确定录入"); | |
309 | + tvTips.setText("快递未录入请输入手机号"); | |
310 | + } | |
311 | + | |
312 | + //已领取 | |
313 | + private void hasGetExpress(ExpressBean expressBean) { | |
314 | + showContents(expressBean); | |
315 | + etExpressCode.setBackground(null); | |
316 | + etName.setBackground(null); | |
317 | + etTel.setBackground(null); | |
318 | + tvCommint.setText("确定"); | |
319 | + tvTips.setText("快递已经被领取"); | |
320 | + } | |
321 | + | |
322 | + //显示信息 | |
323 | + private void showContents(ExpressBean expressBean) { | |
324 | + etExpressCode.setText(expressBean.expressCode); | |
325 | + etTel.setText(expressBean.teacherNum); | |
326 | + etName.setText(expressBean.teacherName); | |
327 | + layout_tel.setVisibility(View.VISIBLE); | |
328 | + layout_name.setVisibility(View.VISIBLE); | |
329 | + layout_express.setVisibility(View.VISIBLE); | |
330 | + etName.setFocusable(false); | |
331 | + etTel.setFocusable(false); | |
332 | + etExpressCode.setFocusable(false); | |
333 | + tvCancle.setVisibility(View.VISIBLE); | |
334 | + } | |
335 | + | |
336 | + Handler mhanlder = new Handler() { | |
337 | + @Override | |
338 | + public void handleMessage(Message message) { | |
339 | + super.handleMessage(message); | |
340 | + switch (message.what) { | |
341 | + //服务绑定成功 service bind success | |
342 | + case MessageType.BaiscMessage.SEVICE_BIND_SUCCESS: | |
343 | +// Toast.makeText(getContext(), getString(R.string.service_bind_success), Toast.LENGTH_SHORT).show(); | |
344 | + mIzkcService = (IZKCService) message.obj; | |
345 | + registerCallbackAndInitScan(); | |
346 | + break; | |
347 | + //服务绑定失败 service bind fail | |
348 | + case MessageType.BaiscMessage.SEVICE_BIND_FAIL: | |
349 | +// Toast.makeText(getContext(), getString(R.string.service_bind_fail), Toast.LENGTH_SHORT).show(); | |
350 | + break; | |
351 | + case MessageType.BaiscMessage.SCAN_RESULT_GET_SUCCESS: | |
352 | + mPresenter.getExpressInfo(text); | |
353 | + break; | |
354 | + case INSERT_SUCCESS: | |
355 | + showExpress(); | |
356 | + break; | |
357 | + } | |
358 | + } | |
359 | + }; | |
360 | + | |
361 | + private void registerCallbackAndInitScan() { | |
362 | + try { | |
363 | + //设置扫描模块 set up scan module | |
364 | + mIzkcService.setModuleFlag(4); | |
365 | + //注册扫描数据回调接口 | |
366 | + mIzkcService.registerCallBack("Scanner", mCallback); | |
367 | + //打开扫描 open scan | |
368 | + mIzkcService.openScan(true); | |
369 | +// btn_scan.setEnabled(true); | |
370 | + } catch (RemoteException e) { | |
371 | + e.printStackTrace(); | |
372 | + } | |
373 | + } | |
374 | + | |
375 | + @Override | |
376 | + public void onDestroy() { | |
377 | + super.onDestroy(); | |
378 | + try { | |
379 | + mIzkcService.unregisterCallBack("Scanner", mCallback); | |
380 | + } catch (RemoteException e) { | |
381 | + e.printStackTrace(); | |
382 | + } | |
383 | + } | |
384 | + | |
385 | + | |
386 | + private class MyPopu extends PopupWindow { | |
387 | + | |
388 | + RecyclerView recyclerView; | |
389 | + MyAdapter myAdapter; | |
390 | + | |
391 | + public MyPopu() { | |
392 | + | |
393 | + View view = LayoutInflater.from(getContext()).inflate(R.layout.popu_mobile, null); | |
394 | + recyclerView = view.findViewById(R.id.recyclerView); | |
395 | + | |
396 | + setWidth(WindowManager.LayoutParams.MATCH_PARENT); | |
397 | + setHeight(WindowManager.LayoutParams.WRAP_CONTENT); | |
398 | + | |
399 | + setFocusable(false); | |
400 | + setOutsideTouchable(true); | |
401 | + setBackgroundDrawable(new BitmapDrawable()); | |
402 | + | |
403 | + setContentView(view); | |
404 | + update(); | |
405 | + } | |
406 | + | |
407 | + public void showDatas(List<String> list) { | |
408 | + if (null == myAdapter) myAdapter = new MyAdapter(); | |
409 | + if (null == recyclerView.getAdapter()) { | |
410 | + recyclerView.setAdapter(myAdapter); | |
411 | + myAdapter.setOnItemClickListener(new OnItemClickListener() { | |
412 | + @Override | |
413 | + public void onItemClickListener(Object object, int position) { | |
414 | + etTel.setText(object.toString()); | |
415 | + mPresenter.getTeacherName(object.toString()); | |
416 | + dismiss(); | |
417 | + } | |
418 | + }); | |
419 | + } | |
420 | + myAdapter.addAll(list); | |
421 | + } | |
422 | + | |
423 | + private class MyAdapter extends BaseRecyclerViewAdapter<String> { | |
424 | + | |
425 | + @Override | |
426 | + public void onAttachedToRecyclerView(RecyclerView recyclerView) { | |
427 | + super.onAttachedToRecyclerView(recyclerView); | |
428 | + LinearLayoutManager layoutManager = new LinearLayoutManager(getContext()); | |
429 | + layoutManager.setOrientation(LinearLayoutManager.VERTICAL); | |
430 | + recyclerView.setLayoutManager(layoutManager); | |
431 | + } | |
432 | + | |
433 | + @Override | |
434 | + public BaseRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | |
435 | + View view = LayoutInflater.from(getContext()).inflate(R.layout.item_mobile, parent, false); | |
436 | + return new MyViewholder(view); | |
437 | + } | |
438 | + | |
439 | + private class MyViewholder extends BaseRecyclerViewHolder<String> { | |
440 | + | |
441 | + TextView tvName; | |
442 | + | |
443 | + public MyViewholder(View itemView) { | |
444 | + super(itemView); | |
445 | + tvName = itemView.findViewById(R.id.tvName); | |
446 | + } | |
447 | + | |
448 | + @Override | |
449 | + public void onBindViewHolder(final String object, final int position) { | |
450 | + tvName.setText(object); | |
451 | + tvName.setOnClickListener(new View.OnClickListener() { | |
452 | + @Override | |
453 | + public void onClick(View view) { | |
454 | + onItemClickListener.onItemClickListener(object, position); | |
455 | + } | |
456 | + }); | |
457 | + } | |
458 | + } | |
459 | + } | |
460 | + | |
461 | + } | |
462 | + | |
463 | +} | ... | ... |
app/src/main/java/com/shunzhi/expressscanner/model/MainModel.java
0 → 100644
... | ... | @@ -0,0 +1,70 @@ |
1 | +package com.shunzhi.expressscanner.model; | |
2 | + | |
3 | +import android.util.Log; | |
4 | + | |
5 | +import com.google.gson.JsonObject; | |
6 | +import com.share.mvpsdk.base.BaseModel; | |
7 | +import com.share.mvpsdk.helper.RetrofitCreateHelper; | |
8 | +import com.share.mvpsdk.helper.RxHelper; | |
9 | +import com.shunzhi.expressscanner.AppConfig; | |
10 | +import com.shunzhi.expressscanner.api.MainApi; | |
11 | +import com.shunzhi.expressscanner.bean.ExpressBean; | |
12 | +import com.shunzhi.expressscanner.contract.MainContract; | |
13 | + | |
14 | +import io.reactivex.Observable; | |
15 | + | |
16 | +/** | |
17 | + * Created by ToaHanDong on 2018/4/24. | |
18 | + */ | |
19 | + | |
20 | +public class MainModel extends BaseModel implements MainContract.IMainModel { | |
21 | + | |
22 | + | |
23 | + public static MainModel newInstance(){ | |
24 | + return new MainModel(); | |
25 | + } | |
26 | + | |
27 | + @Override | |
28 | + public Observable<JsonObject> getTeacherName(String tel) { | |
29 | + return RetrofitCreateHelper.getInstance().createApi(MainApi.class,AppConfig.BASE_URL) | |
30 | + .SearchNameByPhone(tel).compose(RxHelper.<JsonObject>rxSchedulerHelper()); | |
31 | + } | |
32 | + | |
33 | + @Override | |
34 | + public Observable<JsonObject> getExpressInfo(String expressCode,String schoolId) { | |
35 | + return RetrofitCreateHelper.getInstance().createApi(MainApi.class,AppConfig.BASE_URL) | |
36 | + .getExpressInfo(expressCode,schoolId).compose(RxHelper.<JsonObject>rxSchedulerHelper()); | |
37 | + } | |
38 | + | |
39 | + @Override | |
40 | + public Observable<JsonObject> login(String logName, String logPwd) { | |
41 | + return RetrofitCreateHelper.getInstance().login(MainApi.class, AppConfig.BASE_URL) | |
42 | + .login("password",logName,logPwd).compose(RxHelper.<JsonObject>rxSchedulerHelper()); | |
43 | + } | |
44 | + | |
45 | + @Override | |
46 | + public Observable<JsonObject> upExpressInfo(ExpressBean expressBean) { | |
47 | + String schoolId=AppConfig.getAppConfig().get(AppConfig.SCHOOL_ID); | |
48 | + return RetrofitCreateHelper.getInstance().createApi(MainApi.class,AppConfig.BASE_URL) | |
49 | + .InsertExpress(expressBean.expressCode,expressBean.teacherNum,expressBean.teacherName | |
50 | + ,schoolId).compose(RxHelper.<JsonObject>rxSchedulerHelper()); | |
51 | + } | |
52 | + | |
53 | + @Override | |
54 | + public Observable<JsonObject> getCurrentInfo() { | |
55 | + return RetrofitCreateHelper.getInstance().createApi(MainApi.class,AppConfig.BASE_URL) | |
56 | + .getCurrentInfo().compose(RxHelper.<JsonObject>rxSchedulerHelper()); | |
57 | + } | |
58 | + | |
59 | + @Override | |
60 | + public Observable<JsonObject> SearchExpressPhone(String mobile) { | |
61 | + return RetrofitCreateHelper.getInstance().createApi(MainApi.class,AppConfig.BASE_URL) | |
62 | + .SearchExpressPhone(mobile).compose(RxHelper.<JsonObject>rxSchedulerHelper()); | |
63 | + } | |
64 | + | |
65 | + @Override | |
66 | + public Observable<JsonObject> UpdateIsReceive(String ExpressNumber, String schoolId) { | |
67 | + return RetrofitCreateHelper.getInstance().createApi(MainApi.class,AppConfig.BASE_URL) | |
68 | + .UpdateIsReceive(ExpressNumber,schoolId).compose(RxHelper.<JsonObject>rxSchedulerHelper()); | |
69 | + } | |
70 | +} | ... | ... |
app/src/main/java/com/shunzhi/expressscanner/present/MainPresenter.java
0 → 100644
... | ... | @@ -0,0 +1,217 @@ |
1 | +package com.shunzhi.expressscanner.present; | |
2 | + | |
3 | +import android.util.Log; | |
4 | + | |
5 | +import com.google.gson.JsonArray; | |
6 | +import com.google.gson.JsonObject; | |
7 | +import com.share.mvpsdk.RxManager; | |
8 | +import com.share.mvpsdk.utils.OkHttpExceptionUtil; | |
9 | +import com.share.mvpsdk.utils.ToastUtils; | |
10 | +import com.shunzhi.expressscanner.AppConfig; | |
11 | +import com.shunzhi.expressscanner.bean.ExpressBean; | |
12 | +import com.shunzhi.expressscanner.contract.MainContract; | |
13 | +import com.shunzhi.expressscanner.model.MainModel; | |
14 | + | |
15 | +import org.json.JSONObject; | |
16 | + | |
17 | +import java.util.ArrayList; | |
18 | +import java.util.List; | |
19 | + | |
20 | +import io.reactivex.functions.Consumer; | |
21 | +import retrofit2.HttpException; | |
22 | +import timber.log.Timber; | |
23 | + | |
24 | +/** | |
25 | + * Created by ToaHanDong on 2018/4/24. | |
26 | + */ | |
27 | + | |
28 | +public class MainPresenter extends MainContract.MainPresenter { | |
29 | + @Override | |
30 | + public MainContract.IMainModel getModel() { | |
31 | + return MainModel.newInstance(); | |
32 | + } | |
33 | + | |
34 | + @Override | |
35 | + public void onStart() { | |
36 | + | |
37 | + } | |
38 | + | |
39 | + @Override | |
40 | + public void login(String loginName, String loginPwd) { | |
41 | + | |
42 | + mRxManager.register(mIModel.login(loginName, loginPwd).subscribe(new Consumer<JsonObject>() { | |
43 | + @Override | |
44 | + public void accept(JsonObject jsonObject) throws Exception { | |
45 | + String access_token = jsonObject.get("access_token").getAsString(); | |
46 | + AppConfig.getAppConfig().set(AppConfig.ACCESS_TOKEN, access_token); | |
47 | + getCurrentInfo(); | |
48 | + } | |
49 | + }, new Consumer<Throwable>() { | |
50 | + @Override | |
51 | + public void accept(Throwable throwable) throws Exception { | |
52 | + try { | |
53 | + OkHttpExceptionUtil.handOkHttpException((HttpException) throwable); | |
54 | + } catch (Exception e) { | |
55 | + e.printStackTrace(); | |
56 | + } | |
57 | + } | |
58 | + })); | |
59 | + | |
60 | + } | |
61 | + | |
62 | + private void getCurrentInfo() { | |
63 | + | |
64 | + mRxManager.register(mIModel.getCurrentInfo().subscribe(new Consumer<JsonObject>() { | |
65 | + @Override | |
66 | + public void accept(JsonObject jsonObject) throws Exception { | |
67 | + if (jsonObject.get("status").getAsInt() == 1) { | |
68 | + JsonObject data = jsonObject.getAsJsonObject("data"); | |
69 | + AppConfig.getAppConfig().set(AppConfig.CURRENT_USERID, data.get("id").getAsString()); | |
70 | + JsonArray teachClass = data.getAsJsonArray("teachClass"); | |
71 | + if (teachClass.size() > 0) { | |
72 | + JsonObject jsonObject1 = teachClass.get(0).getAsJsonObject(); | |
73 | + AppConfig.getAppConfig().set(AppConfig.SCHOOL_ID, jsonObject1.get("schoolId").getAsString()); | |
74 | + } | |
75 | + } | |
76 | + } | |
77 | + }, new Consumer<Throwable>() { | |
78 | + @Override | |
79 | + public void accept(Throwable throwable) throws Exception { | |
80 | + Log.d("55555", "getCurrentInfo=" + throwable.toString()); | |
81 | + } | |
82 | + })); | |
83 | + | |
84 | + } | |
85 | + | |
86 | + @Override | |
87 | + public void getExpressInfo(String expressCode) { | |
88 | + | |
89 | + String scholId = AppConfig.getAppConfig().get(AppConfig.SCHOOL_ID); | |
90 | + mRxManager.register(mIModel.getExpressInfo(expressCode, scholId).subscribe(new Consumer<JsonObject>() { | |
91 | + @Override | |
92 | + public void accept(JsonObject jsonObject) throws Exception { | |
93 | + if (jsonObject.get("status").getAsInt() == 1) { | |
94 | + JsonArray jsonArray = jsonObject.getAsJsonArray("data"); | |
95 | + ExpressBean expressBean = new ExpressBean(); | |
96 | + if (jsonArray.size() > 0) { | |
97 | + JsonObject exoressBeanObj = jsonArray.get(0).getAsJsonObject(); | |
98 | + expressBean.teacherName = exoressBeanObj.get("userName").getAsString(); | |
99 | + expressBean.teacherNum = exoressBeanObj.get("moilePhone").getAsString(); | |
100 | + expressBean.expressCode = exoressBeanObj.get("expressNumber").getAsString(); | |
101 | + expressBean.state = exoressBeanObj.get("state").getAsInt(); | |
102 | + } else {//未录入快递 | |
103 | + expressBean.state = 2; | |
104 | + } | |
105 | + mIView.showExpressInfo(expressBean); | |
106 | + } | |
107 | + Log.d("55555", "getExpressInfo=" + jsonObject.toString()); | |
108 | + } | |
109 | + }, new Consumer<Throwable>() { | |
110 | + @Override | |
111 | + public void accept(Throwable throwable) throws Exception { | |
112 | + Log.d("55555", "getExpressInfo=" + throwable.toString()); | |
113 | + } | |
114 | + })); | |
115 | + | |
116 | + } | |
117 | + | |
118 | + @Override | |
119 | + public void getTeacherName(String tel) { | |
120 | + mRxManager.register(mIModel.getTeacherName(tel).subscribe(new Consumer<JsonObject>() { | |
121 | + @Override | |
122 | + public void accept(JsonObject jsonObject) throws Exception { | |
123 | + try { | |
124 | + | |
125 | + if (jsonObject.get("status").getAsInt() == 1) { | |
126 | + JsonObject data = jsonObject.getAsJsonObject("data"); | |
127 | + mIView.showTeacherName(data.get("userName").getAsString()); | |
128 | + } else ToastUtils.showToast(jsonObject.get("message").getAsString()); | |
129 | + | |
130 | + } catch (Exception e) { | |
131 | + e.printStackTrace(); | |
132 | + } | |
133 | + } | |
134 | + }, new Consumer<Throwable>() { | |
135 | + @Override | |
136 | + public void accept(Throwable throwable) throws Exception { | |
137 | + | |
138 | + } | |
139 | + })); | |
140 | + } | |
141 | + | |
142 | + //录入快递 | |
143 | + @Override | |
144 | + public void upExpressInfo(ExpressBean expressBean) { | |
145 | + mRxManager.register(mIModel.upExpressInfo(expressBean).subscribe(new Consumer<JsonObject>() { | |
146 | + @Override | |
147 | + public void accept(JsonObject jsonObject) throws Exception { | |
148 | + try { | |
149 | + if (jsonObject.get("status").getAsInt() == 1) { | |
150 | + mIView.showExpressInfoSuccess(true); | |
151 | + } else ToastUtils.showToast(jsonObject.get("message").getAsString()); | |
152 | + } catch (Exception e) { | |
153 | + e.printStackTrace(); | |
154 | + } | |
155 | + } | |
156 | + }, new Consumer<Throwable>() { | |
157 | + @Override | |
158 | + public void accept(Throwable throwable) throws Exception { | |
159 | +// Log.d("55555","upExpressInfo="+throwable.toString()); | |
160 | + } | |
161 | + })); | |
162 | + } | |
163 | + | |
164 | + @Override | |
165 | + public void SearchExpressPhone(String mobile) { | |
166 | + mRxManager.register(mIModel.SearchExpressPhone(mobile).subscribe(new Consumer<JsonObject>() { | |
167 | + @Override | |
168 | + public void accept(JsonObject jsonObject) throws Exception { | |
169 | + try { | |
170 | + Log.d("55555","SearchExpressPhone="+jsonObject.toString()); | |
171 | + if (jsonObject.get("status").getAsInt() == 1) { | |
172 | + List<String> list = new ArrayList<>(); | |
173 | + JsonArray data = jsonObject.getAsJsonArray("data"); | |
174 | + for (int i = 0; i < data.size(); i++) { | |
175 | + JsonObject jsonObject1 = data.get(i).getAsJsonObject(); | |
176 | + list.add(jsonObject1.get("moilePhone").getAsString()); | |
177 | + } | |
178 | + mIView.showSearchModel(list); | |
179 | + } else ToastUtils.showToast(jsonObject.get("message").getAsString()); | |
180 | + } catch (Exception e) { | |
181 | + e.printStackTrace(); | |
182 | + } | |
183 | + } | |
184 | + }, new Consumer<Throwable>() { | |
185 | + @Override | |
186 | + public void accept(Throwable throwable) throws Exception { | |
187 | + Log.d("55555","SearchExpressPhone="+throwable.toString()); | |
188 | + } | |
189 | + })); | |
190 | + } | |
191 | + | |
192 | + /** | |
193 | + * 领取快递 | |
194 | + * @param ExpressNumber | |
195 | + * @param schoolId | |
196 | + */ | |
197 | + @Override | |
198 | + public void UpdateIsReceive(String ExpressNumber, String schoolId) { | |
199 | + mRxManager.register(mIModel.UpdateIsReceive(ExpressNumber,schoolId).subscribe(new Consumer<JsonObject>() { | |
200 | + @Override | |
201 | + public void accept(JsonObject jsonObject) throws Exception { | |
202 | + try { | |
203 | + if (jsonObject.get("status").getAsInt()==1){ | |
204 | + mIView.showUpdateIsReceive(true); | |
205 | + }else ToastUtils.showToast(jsonObject.get("message").getAsString()); | |
206 | + }catch (Exception e){ | |
207 | + e.printStackTrace(); | |
208 | + } | |
209 | + } | |
210 | + }, new Consumer<Throwable>() { | |
211 | + @Override | |
212 | + public void accept(Throwable throwable) throws Exception { | |
213 | + ToastUtils.showToast(throwable.toString()); | |
214 | + } | |
215 | + })); | |
216 | + } | |
217 | +} | ... | ... |
... | ... | @@ -0,0 +1,7 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<selector xmlns:android="http://schemas.android.com/apk/res/android"> | |
3 | + | |
4 | + <item android:state_pressed="true" android:drawable="@drawable/shape_gray"/> | |
5 | + <item android:drawable="@drawable/shape_blue"/> | |
6 | + | |
7 | +</selector> | |
0 | 8 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,8 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<shape xmlns:android="http://schemas.android.com/apk/res/android"> | |
3 | + | |
4 | + <corners android:radius="@dimen/dp_8"/> | |
5 | + | |
6 | + <stroke android:color="@color/gray" android:width="1dp"/> | |
7 | + | |
8 | +</shape> | |
0 | 9 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,33 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
3 | + xmlns:app="http://schemas.android.com/apk/res-auto" | |
4 | + xmlns:tools="http://schemas.android.com/tools" | |
5 | + android:layout_width="match_parent" | |
6 | + android:layout_height="match_parent" | |
7 | + tools:context="com.shunzhi.expressscanner.base.BaseActivity"> | |
8 | + | |
9 | + <android.support.design.widget.AppBarLayout | |
10 | + android:layout_width="match_parent" | |
11 | + android:layout_height="wrap_content" | |
12 | + android:theme="@style/AppTheme.AppBarOverlay"> | |
13 | + | |
14 | + <android.support.v7.widget.Toolbar | |
15 | + android:id="@+id/toolbar" | |
16 | + android:layout_width="match_parent" | |
17 | + android:layout_height="?attr/actionBarSize" | |
18 | + android:background="?attr/colorPrimary" | |
19 | + app:popupTheme="@style/AppTheme.PopupOverlay" /> | |
20 | + | |
21 | + </android.support.design.widget.AppBarLayout> | |
22 | + | |
23 | + <include layout="@layout/content_base" /> | |
24 | + | |
25 | + <android.support.design.widget.FloatingActionButton | |
26 | + android:id="@+id/fab" | |
27 | + android:layout_width="wrap_content" | |
28 | + android:layout_height="wrap_content" | |
29 | + android:layout_gravity="bottom|end" | |
30 | + android:layout_margin="@dimen/fab_margin" | |
31 | + app:srcCompat="@android:drawable/ic_dialog_email" /> | |
32 | + | |
33 | +</android.support.design.widget.CoordinatorLayout> | ... | ... |
app/src/main/res/layout/activity_main.xml
1 | 1 | <?xml version="1.0" encoding="utf-8"?> |
2 | -<android.support.constraint.ConstraintLayout | |
2 | +<FrameLayout | |
3 | 3 | xmlns:android="http://schemas.android.com/apk/res/android" |
4 | 4 | xmlns:tools="http://schemas.android.com/tools" |
5 | 5 | xmlns:app="http://schemas.android.com/apk/res-auto" |
6 | 6 | android:layout_width="match_parent" |
7 | 7 | android:layout_height="match_parent" |
8 | + android:id="@+id/frame" | |
8 | 9 | tools:context="com.shunzhi.expressscanner.MainActivity"> |
9 | 10 | |
10 | - <TextView | |
11 | - android:layout_width="wrap_content" | |
12 | - android:layout_height="wrap_content" | |
13 | - android:text="Hello World!" | |
14 | - app:layout_constraintBottom_toBottomOf="parent" | |
15 | - app:layout_constraintLeft_toLeftOf="parent" | |
16 | - app:layout_constraintRight_toRightOf="parent" | |
17 | - app:layout_constraintTop_toTopOf="parent" /> | |
18 | 11 | |
19 | -</android.support.constraint.ConstraintLayout> | |
12 | +</FrameLayout> | ... | ... |
... | ... | @@ -0,0 +1,11 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
3 | + xmlns:app="http://schemas.android.com/apk/res-auto" | |
4 | + xmlns:tools="http://schemas.android.com/tools" | |
5 | + android:layout_width="match_parent" | |
6 | + android:layout_height="match_parent" | |
7 | + app:layout_behavior="@string/appbar_scrolling_view_behavior" | |
8 | + tools:context="com.shunzhi.expressscanner.base.BaseActivity" | |
9 | + tools:showIn="@layout/activity_base"> | |
10 | + | |
11 | +</android.support.constraint.ConstraintLayout> | ... | ... |
... | ... | @@ -0,0 +1,180 @@ |
1 | +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
2 | + xmlns:tools="http://schemas.android.com/tools" | |
3 | + android:layout_width="match_parent" | |
4 | + android:layout_height="match_parent" | |
5 | + android:background="@color/white" | |
6 | + tools:context="com.shunzhi.expressscanner.fragment.MainFragment"> | |
7 | + | |
8 | + | |
9 | + <LinearLayout | |
10 | + android:layout_width="match_parent" | |
11 | + android:layout_height="wrap_content" | |
12 | + android:layout_gravity="center" | |
13 | + android:layout_marginBottom="@dimen/dp_60" | |
14 | + android:orientation="vertical"> | |
15 | + | |
16 | + <LinearLayout | |
17 | + android:layout_width="match_parent" | |
18 | + android:gravity="center" | |
19 | + android:layout_height="wrap_content" | |
20 | + android:orientation="vertical" | |
21 | + > | |
22 | + <TextView | |
23 | + android:layout_width="wrap_content" | |
24 | + android:layout_height="wrap_content" | |
25 | + android:layout_marginBottom="@dimen/dp_10" | |
26 | + android:text="快递管理系统" | |
27 | + android:textColor="@color/text_color_dark" | |
28 | + android:textSize="@dimen/sp_20" /> | |
29 | + | |
30 | + | |
31 | + <LinearLayout | |
32 | + android:id="@+id/layout_express" | |
33 | + android:layout_width="match_parent" | |
34 | + android:layout_height="wrap_content" | |
35 | + android:layout_marginLeft="10dp" | |
36 | + android:layout_marginRight="10dp" | |
37 | + android:layout_marginTop="@dimen/dp_10" | |
38 | + android:gravity="center"> | |
39 | + | |
40 | + <TextView | |
41 | + android:layout_width="0dp" | |
42 | + android:layout_height="wrap_content" | |
43 | + android:layout_weight="1" | |
44 | + android:gravity="right" | |
45 | + android:text="快递号:" | |
46 | + android:textColor="@color/text_color_dark" | |
47 | + android:textSize="@dimen/sp_14" /> | |
48 | + | |
49 | + <EditText | |
50 | + android:id="@+id/etExpressCode" | |
51 | + android:layout_width="0dp" | |
52 | + android:layout_height="@dimen/avatarSize" | |
53 | + android:layout_marginLeft="@dimen/dp_10" | |
54 | + android:layout_weight="5" | |
55 | + android:background="@drawable/shape_edit" | |
56 | + android:hint="快递单号" | |
57 | + android:maxLines="1" | |
58 | + android:paddingLeft="@dimen/dp_5" | |
59 | + android:singleLine="true" | |
60 | + android:textColor="@color/text_color_dark" | |
61 | + android:textColorHint="@color/gray" | |
62 | + android:textSize="@dimen/sp_14" /> | |
63 | + | |
64 | + </LinearLayout> | |
65 | + | |
66 | + <LinearLayout | |
67 | + android:id="@+id/layout_tel" | |
68 | + android:layout_width="match_parent" | |
69 | + android:layout_height="wrap_content" | |
70 | + android:layout_marginLeft="10dp" | |
71 | + android:layout_marginRight="10dp" | |
72 | + android:layout_marginTop="@dimen/dp_10" | |
73 | + android:gravity="center" | |
74 | + android:visibility="invisible"> | |
75 | + | |
76 | + <TextView | |
77 | + android:layout_width="0dp" | |
78 | + android:layout_height="wrap_content" | |
79 | + android:layout_weight="1" | |
80 | + android:gravity="right" | |
81 | + android:text="手机号:" | |
82 | + android:textColor="@color/text_color_dark" | |
83 | + android:textSize="@dimen/sp_14" /> | |
84 | + | |
85 | + <EditText | |
86 | + android:id="@+id/etTel" | |
87 | + android:layout_width="0dp" | |
88 | + android:layout_height="@dimen/avatarSize" | |
89 | + android:layout_marginLeft="@dimen/dp_10" | |
90 | + android:layout_weight="5" | |
91 | + android:paddingLeft="@dimen/dp_5" | |
92 | + android:background="@drawable/shape_edit" | |
93 | + android:hint="请输入11位手机号" | |
94 | + android:maxLines="1" | |
95 | + android:singleLine="true" | |
96 | + android:textColor="@color/text_color_dark" | |
97 | + android:textColorHint="@color/gray" | |
98 | + android:textSize="@dimen/sp_14" /> | |
99 | + | |
100 | + </LinearLayout> | |
101 | + | |
102 | + <LinearLayout | |
103 | + android:id="@+id/layout_name" | |
104 | + android:layout_width="match_parent" | |
105 | + android:layout_height="wrap_content" | |
106 | + android:layout_marginLeft="10dp" | |
107 | + android:layout_marginRight="10dp" | |
108 | + android:layout_marginTop="@dimen/dp_10" | |
109 | + android:gravity="center" | |
110 | + android:visibility="invisible"> | |
111 | + | |
112 | + <TextView | |
113 | + android:layout_width="0dp" | |
114 | + android:layout_height="wrap_content" | |
115 | + android:layout_weight="1" | |
116 | + android:gravity="right" | |
117 | + android:text="姓名:" | |
118 | + android:textColor="@color/text_color_dark" | |
119 | + android:textSize="@dimen/sp_14" /> | |
120 | + | |
121 | + <EditText | |
122 | + android:id="@+id/etName" | |
123 | + android:layout_width="0dp" | |
124 | + android:layout_height="@dimen/avatarSize" | |
125 | + android:layout_marginLeft="@dimen/dp_10" | |
126 | + android:layout_weight="5" | |
127 | + android:paddingLeft="@dimen/dp_5" | |
128 | + android:background="@drawable/shape_edit" | |
129 | + android:hint="无需输入,根据号码显示姓名" | |
130 | + android:maxLines="1" | |
131 | + android:singleLine="true" | |
132 | + android:textColor="@color/gray" | |
133 | + android:textColorHint="@color/gray" | |
134 | + android:textSize="@dimen/sp_14" /> | |
135 | + | |
136 | + </LinearLayout> | |
137 | + | |
138 | + <Button | |
139 | + android:id="@+id/tvCommint" | |
140 | + android:layout_width="match_parent" | |
141 | + android:layout_height="wrap_content" | |
142 | + android:layout_marginLeft="@dimen/dp_10" | |
143 | + android:layout_marginRight="@dimen/dp_10" | |
144 | + android:layout_marginTop="@dimen/dp_30" | |
145 | + android:background="@drawable/selector_btn" | |
146 | + android:gravity="center" | |
147 | + android:text="确定并扫描快递" | |
148 | + android:textColor="@color/white" | |
149 | + android:textSize="@dimen/sp_16" /> | |
150 | + | |
151 | + </LinearLayout> | |
152 | + <Button | |
153 | + android:id="@+id/tvCancle" | |
154 | + android:layout_width="match_parent" | |
155 | + android:layout_height="wrap_content" | |
156 | + android:layout_marginLeft="@dimen/dp_10" | |
157 | + android:layout_marginRight="@dimen/dp_10" | |
158 | + android:layout_marginTop="@dimen/dp_10" | |
159 | + android:background="@drawable/shape_gray" | |
160 | + android:gravity="center" | |
161 | + android:text="取消" | |
162 | + android:textColor="@color/white" | |
163 | + android:textSize="@dimen/sp_16" | |
164 | + android:visibility="gone" /> | |
165 | + | |
166 | + | |
167 | + </LinearLayout> | |
168 | + | |
169 | + <TextView | |
170 | + android:id="@+id/tvTips" | |
171 | + android:layout_width="wrap_content" | |
172 | + android:layout_height="wrap_content" | |
173 | + android:layout_gravity="bottom|center" | |
174 | + android:layout_marginBottom="60dp" | |
175 | + android:text="提示:请扫描快递" | |
176 | + android:textColor="@color/md_red_500" | |
177 | + android:textSize="@dimen/sp_14" /> | |
178 | + | |
179 | + | |
180 | +</FrameLayout> | ... | ... |
... | ... | @@ -0,0 +1,26 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
3 | + android:layout_width="match_parent" | |
4 | + android:layout_height="?android:actionBarSize"> | |
5 | + | |
6 | + <TextView | |
7 | + android:layout_width="match_parent" | |
8 | + android:layout_height="match_parent" | |
9 | + android:textColor="@color/text_color_dark" | |
10 | + android:textSize="@dimen/sp_14" | |
11 | + android:gravity="center_vertical" | |
12 | + android:layout_gravity="center_vertical" | |
13 | + android:paddingLeft="15dp" | |
14 | + android:id="@+id/tvName" | |
15 | + /> | |
16 | + | |
17 | + <View | |
18 | + android:layout_width="match_parent" | |
19 | + android:layout_height="0.5dp" | |
20 | + android:layout_gravity="bottom" | |
21 | + android:background="@color/gray" | |
22 | + android:layout_marginLeft="@dimen/dp_10" | |
23 | + android:layout_marginRight="@dimen/dp_10" | |
24 | + /> | |
25 | + | |
26 | +</FrameLayout> | |
0 | 27 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,14 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
3 | + android:layout_width="match_parent" | |
4 | + android:layout_marginLeft="10dp" | |
5 | + android:layout_marginRight="10dp" | |
6 | + android:background="@color/white" | |
7 | + android:layout_height="match_parent"> | |
8 | + | |
9 | + <android.support.v7.widget.RecyclerView | |
10 | + android:id="@+id/recyclerView" | |
11 | + android:layout_width="match_parent" | |
12 | + android:layout_height="match_parent"></android.support.v7.widget.RecyclerView> | |
13 | + | |
14 | +</LinearLayout> | |
0 | 15 | \ No newline at end of file | ... | ... |
No preview for this file type
No preview for this file type
app/src/main/res/values/strings.xml
1 | 1 | <resources> |
2 | 2 | <string name="app_name">ExpressScanner</string> |
3 | + | |
4 | + <!-- TODO: Remove or change this placeholder text --> | |
5 | + <string name="hello_blank_fragment">Hello blank fragment</string> | |
6 | + <string name="title_activity_base">BaseActivity</string> | |
7 | + <string name="service_bind_success">服务绑定成功</string> | |
8 | + <string name="service_bind_fail">服务绑定失败</string> | |
3 | 9 | </resources> | ... | ... |
app/src/main/res/values/styles.xml
... | ... | @@ -8,4 +8,13 @@ |
8 | 8 | <item name="colorAccent">@color/colorAccent</item> |
9 | 9 | </style> |
10 | 10 | |
11 | + <style name="AppTheme.NoActionBar"> | |
12 | + <item name="windowActionBar">false</item> | |
13 | + <item name="windowNoTitle">true</item> | |
14 | + </style> | |
15 | + | |
16 | + <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> | |
17 | + | |
18 | + <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" /> | |
19 | + | |
11 | 20 | </resources> | ... | ... |
build.gradle
... | ... | @@ -19,9 +19,49 @@ allprojects { |
19 | 19 | repositories { |
20 | 20 | google() |
21 | 21 | jcenter() |
22 | + maven { url 'https://jitpack.io' } | |
22 | 23 | } |
23 | 24 | } |
24 | 25 | |
25 | 26 | task clean(type: Delete) { |
26 | 27 | delete rootProject.buildDir |
27 | 28 | } |
29 | + | |
30 | + | |
31 | +ext { | |
32 | + // Sdk and tools | |
33 | + minSdkVersion = 16 | |
34 | + targetSdkVersion = 26 | |
35 | + compileSdkVersion = 26 | |
36 | + buildToolsVersion = '26.0.2' | |
37 | + | |
38 | + // App dependencies | |
39 | + supportLibraryVersion = '26.1.0' | |
40 | + guavaVersion = '18.0' | |
41 | + junitVersion = '4.12' | |
42 | + mockitoVersion = '1.10.19' | |
43 | + powerMockito = '1.6.2' | |
44 | + hamcrestVersion = '1.3' | |
45 | + runnerVersion = '0.4.1' | |
46 | + rulesVersion = '0.4.1' | |
47 | + espressoVersion = '2.2.1' | |
48 | + retrofitVersion = '2.2.0' | |
49 | + okhttploggingVersion = '3.4.1' | |
50 | + okhttpVersion = '3.4.1' | |
51 | + rxjavaVersion = '2.0.1' | |
52 | + rxandroidVersion = '2.0.1' | |
53 | + rxbindingVersion = '2.0.0' | |
54 | + rxPerssionsVersion = '0.9.4@aar' | |
55 | + glideVersion = '3.6.1' | |
56 | + glideokhttpVersion = '1.3.1' | |
57 | + photoviewVersion = '1.2.4' | |
58 | + butterknifeVersion = '8.4.0' | |
59 | + fragmentationVersion = '1.1.6' | |
60 | + loggerVersion = '1.15' | |
61 | + circleImageviewVersion = '2.1.0' | |
62 | + BaseRecyclerViewAdapterHelperVersion = '2.9.34' | |
63 | + SwtichButtonVersion = '1.4.6' | |
64 | + PhotoViewVersion = '1.4.1' | |
65 | + BottomSheetVersion = '1.3.0@aar' | |
66 | + glideTransformationVersion = '2.0.1' | |
67 | +} | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +/build | ... | ... |
... | ... | @@ -0,0 +1,129 @@ |
1 | +apply plugin: 'com.android.library' | |
2 | + | |
3 | +android { | |
4 | + compileSdkVersion rootProject.ext.compileSdkVersion | |
5 | + buildToolsVersion rootProject.ext.buildToolsVersion | |
6 | + | |
7 | + | |
8 | + defaultConfig { | |
9 | + minSdkVersion rootProject.ext.minSdkVersion | |
10 | + targetSdkVersion rootProject.ext.targetSdkVersion | |
11 | + versionCode 1 | |
12 | + versionName "1.0" | |
13 | + | |
14 | + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" | |
15 | + | |
16 | + } | |
17 | + | |
18 | + buildTypes { | |
19 | + def BOOLEAN = "boolean" | |
20 | + def TRUE = "true" | |
21 | + def FALSE = "false" | |
22 | + def IS_SHOW_LOG = "IS_SHOW_LOG" | |
23 | + | |
24 | + release { | |
25 | + minifyEnabled false | |
26 | + buildConfigField BOOLEAN, IS_SHOW_LOG, FALSE | |
27 | + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | |
28 | + } | |
29 | + } | |
30 | + publishNonDefault true | |
31 | +} | |
32 | +//repositories { | |
33 | +// flatDir { | |
34 | +// dirs 'libs' //this way we can find the .aar file in libs folder | |
35 | +// } | |
36 | +// google() | |
37 | +//} | |
38 | +dependencies { | |
39 | + implementation fileTree(dir: 'libs', include: ['*.jar']) | |
40 | + | |
41 | + implementation 'com.android.support:appcompat-v7:26.1.0' | |
42 | + implementation 'com.android.support.constraint:constraint-layout:1.0.2' | |
43 | + testImplementation 'junit:junit:4.12' | |
44 | + androidTestImplementation 'com.android.support.test:runner:1.0.1' | |
45 | + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' | |
46 | + | |
47 | + // Android support | |
48 | + compile "com.android.support:appcompat-v7:$rootProject.supportLibraryVersion" | |
49 | + compile "com.android.support:cardview-v7:$rootProject.supportLibraryVersion" | |
50 | + compile "com.android.support:design:$rootProject.supportLibraryVersion" | |
51 | + compile "com.android.support:recyclerview-v7:$rootProject.supportLibraryVersion" | |
52 | + | |
53 | + //delete | |
54 | + compile 'com.yanzhenjie:recyclerview-swipe:1.1.4' | |
55 | + | |
56 | + // Retrofit | |
57 | + compile "com.squareup.retrofit2:retrofit:$rootProject.retrofitVersion" | |
58 | + compile "com.squareup.retrofit2:converter-gson:$rootProject.retrofitVersion" | |
59 | + compile "com.squareup.retrofit2:adapter-rxjava2:$rootProject.retrofitVersion" | |
60 | + compile "com.squareup.okhttp3:logging-interceptor:$rootProject.okhttploggingVersion" | |
61 | + compile "com.squareup.okhttp3:okhttp:$rootProject.okhttpVersion" | |
62 | + | |
63 | + // RxJava | |
64 | + compile "io.reactivex.rxjava2:rxjava:$rootProject.rxjavaVersion" | |
65 | + compile "io.reactivex.rxjava2:rxandroid:$rootProject.rxandroidVersion" | |
66 | + compile "com.jakewharton.rxbinding2:rxbinding:$rootProject.rxbindingVersion" | |
67 | + | |
68 | + // Glide | |
69 | + compile "com.github.bumptech.glide:glide:$rootProject.glideVersion" | |
70 | + compile "com.github.bumptech.glide:okhttp-integration:$rootProject.glideokhttpVersion" | |
71 | + compile "jp.wasabeef:glide-transformations:$rootProject.glideTransformationVersion" | |
72 | + | |
73 | + //Butterknife | |
74 | + compile "com.jakewharton:butterknife:$rootProject.butterknifeVersion" | |
75 | + annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0' | |
76 | + | |
77 | + //fragmentation | |
78 | + compile "me.yokeyword:fragmentation:$rootProject.fragmentationVersion" | |
79 | + | |
80 | + //Logger | |
81 | + compile "com.orhanobut:logger:$rootProject.loggerVersion" | |
82 | + | |
83 | + //circle imageview | |
84 | + compile "de.hdodenhof:circleimageview:$rootProject.circleImageviewVersion" | |
85 | + | |
86 | + //BaseRecyclerViewAdapterHelper | |
87 | + compile "com.github.CymChad:BaseRecyclerViewAdapterHelper:$rootProject.BaseRecyclerViewAdapterHelperVersion" | |
88 | + | |
89 | + //SwitchButton | |
90 | + compile "com.kyleduo.switchbutton:library:$rootProject.SwtichButtonVersion" | |
91 | + | |
92 | + //PhotoView | |
93 | + compile "com.bm.photoview:library:$rootProject.PhotoViewVersion" | |
94 | + | |
95 | + compile "com.cocosw:bottomsheet:$rootProject.BottomSheetVersion" | |
96 | + | |
97 | + //permissions | |
98 | + compile "com.tbruyelle.rxpermissions2:rxpermissions:$rootProject.rxPerssionsVersion" | |
99 | + | |
100 | + //timber | |
101 | + compile 'com.jakewharton.timber:timber:4.5.1' | |
102 | + | |
103 | + //jiaozivideoplayer | |
104 | + compile 'cn.jzvd:jiaozivideoplayer:6.2.7' | |
105 | +// compile(name: 'jiaozivideoplayer-6.2.3', ext: 'aar') | |
106 | + | |
107 | + //轮播图XBanner | |
108 | + compile 'com.xhb:xbanner:1.3.1' | |
109 | + | |
110 | + //省市区联动 | |
111 | + compile 'me.leefeng:citypicker:1.0' | |
112 | + | |
113 | + //日历控件 | |
114 | + compile 'com.github.idic779:monthweekmaterialcalendarview:1.7' | |
115 | + | |
116 | + //标签拖动排序 | |
117 | + compile 'com.huxq17.handygridview:handygridview:1.1.0' | |
118 | + | |
119 | + //xrecyclerview | |
120 | + compile 'com.jcodecraeer:xrecyclerview:1.5.9' | |
121 | + | |
122 | + //悬浮窗 | |
123 | +// compile 'com.github.yhaolpz:FloatWindow:1.0.8' | |
124 | +//数据库 | |
125 | + compile 'com.j256.ormlite:ormlite-core:4.48' | |
126 | + compile 'com.j256.ormlite:ormlite-android:4.48' | |
127 | + | |
128 | + | |
129 | +} | ... | ... |
... | ... | @@ -0,0 +1,21 @@ |
1 | +# Add project specific ProGuard rules here. | |
2 | +# You can control the set of applied configuration files using the | |
3 | +# proguardFiles setting in build.gradle. | |
4 | +# | |
5 | +# For more details, see | |
6 | +# http://developer.android.com/guide/developing/tools/proguard.html | |
7 | + | |
8 | +# If your project uses WebView with JS, uncomment the following | |
9 | +# and specify the fully qualified class name to the JavaScript interface | |
10 | +# class: | |
11 | +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { | |
12 | +# public *; | |
13 | +#} | |
14 | + | |
15 | +# Uncomment this to preserve the line number information for | |
16 | +# debugging stack traces. | |
17 | +#-keepattributes SourceFile,LineNumberTable | |
18 | + | |
19 | +# If you keep the line number information, uncomment this to | |
20 | +# hide the original source file name. | |
21 | +#-renamesourcefileattribute SourceFile | ... | ... |
mvpsdk/src/androidTest/java/com/share/mvpsdk/ExampleInstrumentedTest.java
0 → 100644
... | ... | @@ -0,0 +1,26 @@ |
1 | +package com.share.mvpsdk; | |
2 | + | |
3 | +import android.content.Context; | |
4 | +import android.support.test.InstrumentationRegistry; | |
5 | +import android.support.test.runner.AndroidJUnit4; | |
6 | + | |
7 | +import org.junit.Test; | |
8 | +import org.junit.runner.RunWith; | |
9 | + | |
10 | +import static org.junit.Assert.*; | |
11 | + | |
12 | +/** | |
13 | + * Instrumented test, which will execute on an Android device. | |
14 | + * | |
15 | + * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> | |
16 | + */ | |
17 | +@RunWith(AndroidJUnit4.class) | |
18 | +public class ExampleInstrumentedTest { | |
19 | + @Test | |
20 | + public void useAppContext() throws Exception { | |
21 | + // Context of the app under test. | |
22 | + Context appContext = InstrumentationRegistry.getTargetContext(); | |
23 | + | |
24 | + assertEquals("com.share.mvpsdk.test", appContext.getPackageName()); | |
25 | + } | |
26 | +} | ... | ... |
... | ... | @@ -0,0 +1,111 @@ |
1 | +package com.share.mvpsdk; | |
2 | + | |
3 | +import android.annotation.SuppressLint; | |
4 | +import android.app.Activity; | |
5 | +import android.app.ActivityManager; | |
6 | +import android.content.Context; | |
7 | + | |
8 | +import java.util.Stack; | |
9 | + | |
10 | +/** | |
11 | + * Created by Horrarndoo on 2017/4/5. | |
12 | + * <p> | |
13 | + * AppManager 管理Activity栈 | |
14 | + */ | |
15 | + | |
16 | +public class AppManager { | |
17 | + private static Stack<Activity> activityStack; | |
18 | + private static AppManager instance; | |
19 | + | |
20 | + private AppManager() { | |
21 | + } | |
22 | + | |
23 | + /** | |
24 | + * 单一实例 | |
25 | + */ | |
26 | + public static AppManager getAppManager() { | |
27 | + if (instance == null) { | |
28 | + instance = new AppManager(); | |
29 | + } | |
30 | + return instance; | |
31 | + } | |
32 | + | |
33 | + /** | |
34 | + * 添加Activity到堆栈 | |
35 | + */ | |
36 | + public void addActivity(Activity activity) { | |
37 | + if (activityStack == null) { | |
38 | + activityStack = new Stack<Activity>(); | |
39 | + } | |
40 | + activityStack.add(activity); | |
41 | + } | |
42 | + | |
43 | + /** | |
44 | + * 获取当前Activity(堆栈中最后一个压入的) | |
45 | + */ | |
46 | + public Activity currentActivity() { | |
47 | + Activity activity = activityStack.lastElement(); | |
48 | + return activity; | |
49 | + } | |
50 | + | |
51 | + /** | |
52 | + * 结束当前Activity(堆栈中最后一个压入的) | |
53 | + */ | |
54 | + public void finishActivity() { | |
55 | + Activity activity = activityStack.lastElement(); | |
56 | + finishActivity(activity); | |
57 | + } | |
58 | + | |
59 | + /** | |
60 | + * 结束指定的Activity | |
61 | + */ | |
62 | + public void finishActivity(Activity activity) { | |
63 | + if (activity != null) { | |
64 | + activityStack.remove(activity); | |
65 | + activity.finish(); | |
66 | + activity = null; | |
67 | + } | |
68 | + } | |
69 | + | |
70 | + /** | |
71 | + * 结束指定类名的Activity | |
72 | + */ | |
73 | + public void finishActivity(Class<?> cls) { | |
74 | + for (Activity activity : activityStack) { | |
75 | + if (activity.getClass().equals(cls)) { | |
76 | + finishActivity(activity); | |
77 | + } | |
78 | + } | |
79 | + } | |
80 | + | |
81 | + /** | |
82 | + * 结束所有Activity | |
83 | + */ | |
84 | + public void finishAllActivity() { | |
85 | + for (int i = 0, size = activityStack.size(); i < size; i++) { | |
86 | + if (null != activityStack.get(i)) { | |
87 | + activityStack.get(i).finish(); | |
88 | + } | |
89 | + } | |
90 | + activityStack.clear(); | |
91 | + } | |
92 | + | |
93 | + /** | |
94 | + * 退出应用程序 | |
95 | + */ | |
96 | + @SuppressLint("MissingPermission") | |
97 | + public void AppExit(Context context) { | |
98 | + try { | |
99 | + finishAllActivity(); | |
100 | + ActivityManager activityMgr = | |
101 | + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); | |
102 | + activityMgr.killBackgroundProcesses(context.getPackageName()); | |
103 | + System.exit(0); | |
104 | + } catch (Exception e) { | |
105 | + } | |
106 | + } | |
107 | + | |
108 | + public boolean isAppExit() { | |
109 | + return activityStack == null || activityStack.isEmpty(); | |
110 | + } | |
111 | +} | ... | ... |
... | ... | @@ -0,0 +1,23 @@ |
1 | +package com.share.mvpsdk; | |
2 | + | |
3 | + | |
4 | +import io.reactivex.disposables.CompositeDisposable; | |
5 | +import io.reactivex.disposables.Disposable; | |
6 | + | |
7 | +/** | |
8 | + * Created by Horrarndoo on 2017/9/12. | |
9 | + * <p> | |
10 | + * 用于管理Rxjava 注册订阅和取消订阅 | |
11 | + */ | |
12 | + | |
13 | +public class RxManager { | |
14 | + private CompositeDisposable mCompositeDisposable = new CompositeDisposable();// 管理订阅者者 | |
15 | + | |
16 | + public void register(Disposable d) { | |
17 | + mCompositeDisposable.add(d); | |
18 | + } | |
19 | + | |
20 | + public void unSubscribe() { | |
21 | + mCompositeDisposable.dispose();// 取消订阅 | |
22 | + } | |
23 | +} | |
0 | 24 | \ No newline at end of file | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/adapter/FragmentAdapter.java
0 → 100644
... | ... | @@ -0,0 +1,42 @@ |
1 | +package com.share.mvpsdk.adapter; | |
2 | + | |
3 | + | |
4 | +import android.support.v4.app.Fragment; | |
5 | +import android.support.v4.app.FragmentManager; | |
6 | +import android.support.v4.app.FragmentStatePagerAdapter; | |
7 | +import android.support.v4.view.PagerAdapter; | |
8 | +import android.view.ViewGroup; | |
9 | + | |
10 | +import java.util.List; | |
11 | + | |
12 | +/** | |
13 | + * Created by Horrarndoo on 2017/9/7. | |
14 | + * <p> | |
15 | + */ | |
16 | +public class FragmentAdapter extends FragmentStatePagerAdapter { | |
17 | + private List<Fragment> fragments; | |
18 | + | |
19 | + public FragmentAdapter(FragmentManager fm, List<Fragment> fragments) { | |
20 | + super(fm); | |
21 | + this.fragments = fragments; | |
22 | + } | |
23 | + | |
24 | + @Override | |
25 | + public Fragment getItem(int position) { | |
26 | + return fragments.get(position); | |
27 | + } | |
28 | + | |
29 | + @Override | |
30 | + public int getCount() { | |
31 | + return fragments == null ? 0 : fragments.size(); | |
32 | + } | |
33 | + | |
34 | + public int getItemPosition(Object object) { | |
35 | + return PagerAdapter.POSITION_NONE; | |
36 | + } | |
37 | + | |
38 | + @Override | |
39 | + public void destroyItem(ViewGroup container, int position, Object object) { | |
40 | + // super.destroyItem(container, position, object); | |
41 | + } | |
42 | +} | |
0 | 43 | \ No newline at end of file | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/anim/AnimManager.java
0 → 100644
... | ... | @@ -0,0 +1,75 @@ |
1 | +package com.share.mvpsdk.anim; | |
2 | + | |
3 | +import android.content.Context; | |
4 | +import android.os.Build; | |
5 | +import android.support.annotation.NonNull; | |
6 | +import android.view.View; | |
7 | +import android.view.animation.AnimationUtils; | |
8 | + | |
9 | +/** | |
10 | + * Created by Horrarndoo on 2017/9/11. | |
11 | + * <p> | |
12 | + */ | |
13 | + | |
14 | +public class AnimManager { | |
15 | + /** | |
16 | + * Alpha and scaleX 动画 | |
17 | + * Alpha 0->1 | |
18 | + * ScaleX 0.8->1 | |
19 | + * | |
20 | + * @param context context | |
21 | + * @param view view | |
22 | + * @param startDelay 动画开始前延时(ms) | |
23 | + * @param duration 动画持续时间(ms) | |
24 | + */ | |
25 | + public static void animAlphaAndScaleX(Context context, @NonNull View view, int startDelay, int | |
26 | + duration) { | |
27 | + view.setAlpha(0f); | |
28 | + view.setScaleX(0.8f); | |
29 | + | |
30 | + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
31 | + view.animate() | |
32 | + .alpha(1f) | |
33 | + .scaleX(1f) | |
34 | + .setStartDelay(startDelay) | |
35 | + .setDuration(duration) | |
36 | + .setInterpolator(AnimUtils.getFastOutSlowInInterpolator(context)) | |
37 | + .start(); | |
38 | + }else{ | |
39 | + view.animate() | |
40 | + .alpha(1f) | |
41 | + .scaleX(1f) | |
42 | + .setStartDelay(startDelay) | |
43 | + .setDuration(duration) | |
44 | + .setInterpolator(AnimationUtils.loadInterpolator(context, android.R.interpolator.linear)) | |
45 | + .start(); | |
46 | + } | |
47 | + } | |
48 | + | |
49 | + /** | |
50 | + * Alpha and scale X Y 动画 | |
51 | + * Alpha 0->1 | |
52 | + * ScaleX 0->1 | |
53 | + * ScaleY 0->1 | |
54 | + * | |
55 | + * @param context context | |
56 | + * @param view view | |
57 | + * @param startDelay 动画开始前延时(ms) | |
58 | + * @param duration 动画持续时间(ms) | |
59 | + */ | |
60 | + public static void animAlphaAndScale(Context context, @NonNull View view, int startDelay, int | |
61 | + duration) { | |
62 | + view.setAlpha(0f); | |
63 | + view.setScaleX(0f); | |
64 | + view.setScaleY(0f); | |
65 | + | |
66 | + view.animate() | |
67 | + .alpha(1f) | |
68 | + .scaleX(1f) | |
69 | + .scaleY(1f) | |
70 | + .setStartDelay(startDelay) | |
71 | + .setDuration(duration) | |
72 | + .setInterpolator(AnimationUtils.loadInterpolator(context, | |
73 | + android.R.interpolator.overshoot)).start(); | |
74 | + } | |
75 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/anim/AnimUtils.java
0 → 100644
... | ... | @@ -0,0 +1,330 @@ |
1 | +/* | |
2 | + * Copyright 2015 Google Inc. | |
3 | + * | |
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | + * you may not use this file except in compliance with the License. | |
6 | + * You may obtain a copy of the License at | |
7 | + * | |
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | + * | |
10 | + * Unless required by applicable law or agreed to in writing, software | |
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | + * See the License for the specific language governing permissions and | |
14 | + * limitations under the License. | |
15 | + */ | |
16 | + | |
17 | +package com.share.mvpsdk.anim; | |
18 | + | |
19 | +import android.animation.Animator; | |
20 | +import android.animation.TimeInterpolator; | |
21 | +import android.content.Context; | |
22 | +import android.os.Build; | |
23 | +import android.support.annotation.RequiresApi; | |
24 | +import android.transition.Transition; | |
25 | +import android.util.ArrayMap; | |
26 | +import android.util.Property; | |
27 | +import android.view.animation.AnimationUtils; | |
28 | +import android.view.animation.Interpolator; | |
29 | + | |
30 | +import java.util.ArrayList; | |
31 | + | |
32 | +/** | |
33 | + * Utility methods for working with animations. | |
34 | + */ | |
35 | +public class AnimUtils { | |
36 | + | |
37 | + private AnimUtils() { } | |
38 | + | |
39 | + private static Interpolator fastOutSlowIn; | |
40 | + private static Interpolator fastOutLinearIn; | |
41 | + private static Interpolator linearOutSlowIn; | |
42 | + | |
43 | + public static Interpolator getFastOutSlowInInterpolator(Context context) { | |
44 | + if (fastOutSlowIn == null) { | |
45 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
46 | + fastOutSlowIn = AnimationUtils.loadInterpolator(context, | |
47 | + android.R.interpolator.fast_out_slow_in); | |
48 | + } | |
49 | + } | |
50 | + return fastOutSlowIn; | |
51 | + } | |
52 | + | |
53 | + public static Interpolator getFastOutLinearInInterpolator(Context context) { | |
54 | + if (fastOutLinearIn == null) { | |
55 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
56 | + fastOutLinearIn = AnimationUtils.loadInterpolator(context, | |
57 | + android.R.interpolator.fast_out_linear_in); | |
58 | + } | |
59 | + } | |
60 | + return fastOutLinearIn; | |
61 | + } | |
62 | + | |
63 | + public static Interpolator getLinearOutSlowInInterpolator(Context context) { | |
64 | + if (linearOutSlowIn == null) { | |
65 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
66 | + linearOutSlowIn = AnimationUtils.loadInterpolator(context, | |
67 | + android.R.interpolator.linear_out_slow_in); | |
68 | + } | |
69 | + } | |
70 | + return linearOutSlowIn; | |
71 | + } | |
72 | + | |
73 | + /** | |
74 | + * Linear interpolate between a and b with parameter t. | |
75 | + */ | |
76 | + public static float lerp(float a, float b, float t) { | |
77 | + return a + (b - a) * t; | |
78 | + } | |
79 | + | |
80 | + | |
81 | + /** | |
82 | + * An implementation of {@link Property} to be used specifically with fields of | |
83 | + * type | |
84 | + * <code>float</code>. This type-specific subclass enables performance benefit by allowing | |
85 | + * calls to a {@link #set(Object, Float) set()} function that takes the primitive | |
86 | + * <code>float</code> type and avoids autoboxing and other overhead associated with the | |
87 | + * <code>Float</code> class. | |
88 | + * | |
89 | + * @param <T> The class on which the Property is declared. | |
90 | + **/ | |
91 | + public static abstract class FloatProperty<T> extends Property<T, Float> { | |
92 | + public FloatProperty(String name) { | |
93 | + super(Float.class, name); | |
94 | + } | |
95 | + | |
96 | + /** | |
97 | + * A type-specific override of the {@link #set(Object, Float)} that is faster when dealing | |
98 | + * with fields of type <code>float</code>. | |
99 | + */ | |
100 | + public abstract void setValue(T object, float value); | |
101 | + | |
102 | + @Override | |
103 | + final public void set(T object, Float value) { | |
104 | + setValue(object, value); | |
105 | + } | |
106 | + } | |
107 | + | |
108 | + /** | |
109 | + * An implementation of {@link Property} to be used specifically with fields of | |
110 | + * type | |
111 | + * <code>int</code>. This type-specific subclass enables performance benefit by allowing | |
112 | + * calls to a {@link #set(Object, Integer) set()} function that takes the primitive | |
113 | + * <code>int</code> type and avoids autoboxing and other overhead associated with the | |
114 | + * <code>Integer</code> class. | |
115 | + * | |
116 | + * @param <T> The class on which the Property is declared. | |
117 | + */ | |
118 | + public static abstract class IntProperty<T> extends Property<T, Integer> { | |
119 | + | |
120 | + public IntProperty(String name) { | |
121 | + super(Integer.class, name); | |
122 | + } | |
123 | + | |
124 | + /** | |
125 | + * A type-specific override of the {@link #set(Object, Integer)} that is faster when dealing | |
126 | + * with fields of type <code>int</code>. | |
127 | + */ | |
128 | + public abstract void setValue(T object, int value); | |
129 | + | |
130 | + @Override | |
131 | + final public void set(T object, Integer value) { | |
132 | + setValue(object, value.intValue()); | |
133 | + } | |
134 | + | |
135 | + } | |
136 | + | |
137 | + /** | |
138 | + * https://halfthought.wordpress.com/2014/11/07/reveal-transition/ | |
139 | + * <p/> | |
140 | + * Interrupting Activity transitions can yield an OperationNotSupportedException when the | |
141 | + * transition tries to pause the animator. Yikes! We can fix this by wrapping the Animator: | |
142 | + */ | |
143 | + @RequiresApi(api = Build.VERSION_CODES.KITKAT) | |
144 | + public static class NoPauseAnimator extends Animator { | |
145 | + private final Animator mAnimator; | |
146 | + private final ArrayMap<AnimatorListener, AnimatorListener> mListeners = | |
147 | + new ArrayMap<AnimatorListener, AnimatorListener>(); | |
148 | + | |
149 | + public NoPauseAnimator(Animator animator) { | |
150 | + mAnimator = animator; | |
151 | + } | |
152 | + | |
153 | + @RequiresApi(api = Build.VERSION_CODES.KITKAT) | |
154 | + @Override | |
155 | + public void addListener(AnimatorListener listener) { | |
156 | + AnimatorListener wrapper = new AnimatorListenerWrapper(this, listener); | |
157 | + if (!mListeners.containsKey(listener)) { | |
158 | + mListeners.put(listener, wrapper); | |
159 | + mAnimator.addListener(wrapper); | |
160 | + } | |
161 | + } | |
162 | + | |
163 | + @Override | |
164 | + public void cancel() { | |
165 | + mAnimator.cancel(); | |
166 | + } | |
167 | + | |
168 | + @Override | |
169 | + public void end() { | |
170 | + mAnimator.end(); | |
171 | + } | |
172 | + | |
173 | + @Override | |
174 | + public long getDuration() { | |
175 | + return mAnimator.getDuration(); | |
176 | + } | |
177 | + | |
178 | + @Override | |
179 | + public TimeInterpolator getInterpolator() { | |
180 | + return mAnimator.getInterpolator(); | |
181 | + } | |
182 | + | |
183 | + @Override | |
184 | + public void setInterpolator(TimeInterpolator timeInterpolator) { | |
185 | + mAnimator.setInterpolator(timeInterpolator); | |
186 | + } | |
187 | + | |
188 | + @Override | |
189 | + public ArrayList<AnimatorListener> getListeners() { | |
190 | + return new ArrayList<AnimatorListener>(mListeners.keySet()); | |
191 | + } | |
192 | + | |
193 | + @Override | |
194 | + public long getStartDelay() { | |
195 | + return mAnimator.getStartDelay(); | |
196 | + } | |
197 | + | |
198 | + @Override | |
199 | + public void setStartDelay(long delayMS) { | |
200 | + mAnimator.setStartDelay(delayMS); | |
201 | + } | |
202 | + | |
203 | + @Override | |
204 | + public boolean isPaused() { | |
205 | + return mAnimator.isPaused(); | |
206 | + } | |
207 | + | |
208 | + @Override | |
209 | + public boolean isRunning() { | |
210 | + return mAnimator.isRunning(); | |
211 | + } | |
212 | + | |
213 | + @Override | |
214 | + public boolean isStarted() { | |
215 | + return mAnimator.isStarted(); | |
216 | + } | |
217 | + | |
218 | + /* We don't want to override pause or resume methods because we don't want them | |
219 | + * to affect mAnimator. | |
220 | + public void pause(); | |
221 | + | |
222 | + public void resume(); | |
223 | + | |
224 | + public void addPauseListener(AnimatorPauseListener listener); | |
225 | + | |
226 | + public void removePauseListener(AnimatorPauseListener listener); | |
227 | + */ | |
228 | + | |
229 | + @Override | |
230 | + public void removeAllListeners() { | |
231 | + mListeners.clear(); | |
232 | + mAnimator.removeAllListeners(); | |
233 | + } | |
234 | + | |
235 | + @Override | |
236 | + public void removeListener(AnimatorListener listener) { | |
237 | + AnimatorListener wrapper = mListeners.get(listener); | |
238 | + if (wrapper != null) { | |
239 | + mListeners.remove(listener); | |
240 | + mAnimator.removeListener(wrapper); | |
241 | + } | |
242 | + } | |
243 | + | |
244 | + @Override | |
245 | + public Animator setDuration(long durationMS) { | |
246 | + mAnimator.setDuration(durationMS); | |
247 | + return this; | |
248 | + } | |
249 | + | |
250 | + @Override | |
251 | + public void setTarget(Object target) { | |
252 | + mAnimator.setTarget(target); | |
253 | + } | |
254 | + | |
255 | + @Override | |
256 | + public void setupEndValues() { | |
257 | + mAnimator.setupEndValues(); | |
258 | + } | |
259 | + | |
260 | + @Override | |
261 | + public void setupStartValues() { | |
262 | + mAnimator.setupStartValues(); | |
263 | + } | |
264 | + | |
265 | + @Override | |
266 | + public void start() { | |
267 | + mAnimator.start(); | |
268 | + } | |
269 | + } | |
270 | + | |
271 | + static class AnimatorListenerWrapper implements Animator.AnimatorListener { | |
272 | + private final Animator mAnimator; | |
273 | + private final Animator.AnimatorListener mListener; | |
274 | + | |
275 | + public AnimatorListenerWrapper(Animator animator, Animator.AnimatorListener listener) { | |
276 | + mAnimator = animator; | |
277 | + mListener = listener; | |
278 | + } | |
279 | + | |
280 | + @Override | |
281 | + public void onAnimationStart(Animator animator) { | |
282 | + mListener.onAnimationStart(mAnimator); | |
283 | + } | |
284 | + | |
285 | + @Override | |
286 | + public void onAnimationEnd(Animator animator) { | |
287 | + mListener.onAnimationEnd(mAnimator); | |
288 | + } | |
289 | + | |
290 | + @Override | |
291 | + public void onAnimationCancel(Animator animator) { | |
292 | + mListener.onAnimationCancel(mAnimator); | |
293 | + } | |
294 | + | |
295 | + @Override | |
296 | + public void onAnimationRepeat(Animator animator) { | |
297 | + mListener.onAnimationRepeat(mAnimator); | |
298 | + } | |
299 | + } | |
300 | + | |
301 | + @RequiresApi(api = Build.VERSION_CODES.KITKAT) | |
302 | + public static class TransitionListenerAdapter implements Transition.TransitionListener { | |
303 | + | |
304 | + @Override | |
305 | + public void onTransitionStart(Transition transition) { | |
306 | + | |
307 | + } | |
308 | + | |
309 | + @Override | |
310 | + public void onTransitionEnd(Transition transition) { | |
311 | + | |
312 | + } | |
313 | + | |
314 | + @Override | |
315 | + public void onTransitionCancel(Transition transition) { | |
316 | + | |
317 | + } | |
318 | + | |
319 | + @Override | |
320 | + public void onTransitionPause(Transition transition) { | |
321 | + | |
322 | + } | |
323 | + | |
324 | + @Override | |
325 | + public void onTransitionResume(Transition transition) { | |
326 | + | |
327 | + } | |
328 | + } | |
329 | + | |
330 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/anim/ToolbarAnimManager.java
0 → 100644
... | ... | @@ -0,0 +1,93 @@ |
1 | +package com.share.mvpsdk.anim; | |
2 | + | |
3 | +import android.content.Context; | |
4 | +import android.support.annotation.NonNull; | |
5 | +import android.support.v7.widget.ActionMenuView; | |
6 | +import android.support.v7.widget.Toolbar; | |
7 | +import android.view.View; | |
8 | +import android.widget.ImageButton; | |
9 | +import android.widget.TextView; | |
10 | + | |
11 | +/** | |
12 | + * Created by Horrarndoo on 2017/9/11. | |
13 | + * <p> | |
14 | + * Toolbar动画Manager | |
15 | + */ | |
16 | + | |
17 | +public class ToolbarAnimManager { | |
18 | + /** | |
19 | + * Toolbar 进场动画 | |
20 | + * <p> | |
21 | + * Textview&ActionMenuView渐变动画 | |
22 | + * | |
23 | + * @param context context | |
24 | + * @param toolbar toolbar | |
25 | + */ | |
26 | + public static void animIn(Context context, @NonNull Toolbar toolbar) { | |
27 | + ImageButton ibIcon = null; | |
28 | + TextView tvTitle = null; | |
29 | + ActionMenuView amvTheme = null; | |
30 | + int childCount = toolbar.getChildCount(); | |
31 | + for (int i = 0; i < childCount; i++) { | |
32 | + View child = toolbar.getChildAt(i); | |
33 | + if(child instanceof ImageButton) { | |
34 | + ibIcon = (ImageButton) child; | |
35 | + continue; | |
36 | + } | |
37 | + | |
38 | + if (child instanceof ActionMenuView) { | |
39 | + amvTheme = (ActionMenuView) child; | |
40 | + continue; | |
41 | + } | |
42 | + | |
43 | + if (child instanceof TextView) | |
44 | + tvTitle = (TextView) child; | |
45 | + } | |
46 | + | |
47 | + if(ibIcon != null) | |
48 | + animNavigationIcon(context, ibIcon); | |
49 | + | |
50 | + if(tvTitle != null) | |
51 | + animTitle(context, tvTitle); | |
52 | + | |
53 | + if(amvTheme != null) | |
54 | + animMenu(context, amvTheme); | |
55 | + } | |
56 | + | |
57 | + /** | |
58 | + * Toolbar Title动画 | |
59 | + * <p> | |
60 | + * NavigationIcon渐变动画 | |
61 | + * | |
62 | + * @param context context | |
63 | + * @param imageButton 执行动画的view | |
64 | + */ | |
65 | + public static void animNavigationIcon(Context context, @NonNull ImageButton imageButton) { | |
66 | + AnimManager.animAlphaAndScaleX(context, imageButton, 500, 900); | |
67 | + } | |
68 | + | |
69 | + /** | |
70 | + * Toolbar Title动画 | |
71 | + * <p> | |
72 | + * ActionMenuView渐变动画 | |
73 | + * | |
74 | + * @param context context | |
75 | + * @param textView 执行动画的view | |
76 | + */ | |
77 | + public static void animTitle(Context context, @NonNull TextView textView) { | |
78 | + AnimManager.animAlphaAndScaleX(context, textView, 500, 900); | |
79 | + } | |
80 | + | |
81 | + /** | |
82 | + * Toolbar ActionMenuView动画 | |
83 | + * <p> | |
84 | + * ActionMenuView渐变动画 | |
85 | + * | |
86 | + * @param context context | |
87 | + * @param avm 执行动画的view | |
88 | + */ | |
89 | + public static void animMenu(Context context, @NonNull ActionMenuView avm) { | |
90 | + AnimManager.animAlphaAndScale(context, avm, 500, 200); // filter | |
91 | + AnimManager.animAlphaAndScale(context, avm, 700, 200); // overflow | |
92 | + } | |
93 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/BaseModel.java
0 → 100644
mvpsdk/src/main/java/com/share/mvpsdk/base/BasePresenter.java
0 → 100644
... | ... | @@ -0,0 +1,53 @@ |
1 | +package com.share.mvpsdk.base; | |
2 | + | |
3 | +import android.support.annotation.NonNull; | |
4 | + | |
5 | +import com.share.mvpsdk.RxManager; | |
6 | + | |
7 | + | |
8 | +/** | |
9 | + * Created by Horrarndoo on 2017/4/25. | |
10 | + * <p> | |
11 | + * base presenter | |
12 | + */ | |
13 | + | |
14 | +public abstract class BasePresenter<M, V> { | |
15 | + public M mIModel; | |
16 | + public V mIView; | |
17 | + protected RxManager mRxManager = new RxManager(); | |
18 | + | |
19 | + /** | |
20 | + * 返回presenter想持有的Model引用 | |
21 | + * | |
22 | + * @return presenter持有的Model引用 | |
23 | + */ | |
24 | + public abstract M getModel(); | |
25 | + | |
26 | + /** | |
27 | + * 绑定IModel和IView的引用 | |
28 | + * | |
29 | + * @param m model | |
30 | + * @param v view | |
31 | + */ | |
32 | + public void attachMV(@NonNull M m, @NonNull V v) { | |
33 | + this.mIModel = m; | |
34 | + this.mIView = v; | |
35 | + this.onStart(); | |
36 | + } | |
37 | + | |
38 | + /** | |
39 | + * 解绑IModel和IView | |
40 | + */ | |
41 | + public void detachMV() { | |
42 | + mRxManager.unSubscribe(); | |
43 | + mIView = null; | |
44 | + mIModel = null; | |
45 | + } | |
46 | + | |
47 | + /** | |
48 | + * IView和IModel绑定完成立即执行 | |
49 | + * <p> | |
50 | + * 实现类实现绑定完成后的逻辑,例如数据初始化等,界面初始化, 更新等 | |
51 | + */ | |
52 | + public abstract void onStart(); | |
53 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/IBaseActivity.java
0 → 100644
... | ... | @@ -0,0 +1,35 @@ |
1 | +package com.share.mvpsdk.base; | |
2 | + | |
3 | +import android.os.Bundle; | |
4 | +import android.support.annotation.NonNull; | |
5 | + | |
6 | +/** | |
7 | + * Created by Horrarndoo on 2017/9/6. | |
8 | + * <p> | |
9 | + * BaseActivity接口 | |
10 | + */ | |
11 | + | |
12 | +public interface IBaseActivity extends IBaseView { | |
13 | + /** | |
14 | + * 跳往新的Activity | |
15 | + * | |
16 | + * @param clz 要跳往的Activity | |
17 | + */ | |
18 | + void startNewActivity(@NonNull Class<?> clz); | |
19 | + | |
20 | + /** | |
21 | + * 跳往新的Activity | |
22 | + * | |
23 | + * @param clz 要跳往的Activity | |
24 | + * @param bundle 携带的bundle数据 | |
25 | + */ | |
26 | + void startNewActivity(@NonNull Class<?> clz, Bundle bundle); | |
27 | + | |
28 | + /** | |
29 | + * 跳往新的Activity | |
30 | + * @param clz 要跳转的Activity | |
31 | + * @param bundle bundel数据 | |
32 | + * @param requestCode requestCode | |
33 | + */ | |
34 | + void startNewActivityForResult(@NonNull Class<?> clz, Bundle bundle, int requestCode); | |
35 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/IBaseFragment.java
0 → 100644
... | ... | @@ -0,0 +1,92 @@ |
1 | +package com.share.mvpsdk.base; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | +import android.os.Bundle; | |
5 | +import android.support.annotation.NonNull; | |
6 | + | |
7 | +import me.yokeyword.fragmentation.SupportFragment; | |
8 | + | |
9 | +/** | |
10 | + * Created by Horrarndoo on 2017/9/6. | |
11 | + * <p> | |
12 | + * BaseFragment接口 | |
13 | + */ | |
14 | + | |
15 | +public interface IBaseFragment extends IBaseView { | |
16 | + /** | |
17 | + * 出栈到目标fragment | |
18 | + * | |
19 | + * @param targetFragmentClass 目标fragment | |
20 | + * @param includeTargetFragment 是否包含该fragment | |
21 | + * true 目标fragment也出栈 | |
22 | + * <p> | |
23 | + * false 出栈到目标fragment,目标fragment不出栈 | |
24 | + */ | |
25 | + void popToFragment(Class<?> targetFragmentClass, boolean includeTargetFragment); | |
26 | + | |
27 | + /** | |
28 | + * 跳往新的Fragment | |
29 | + * | |
30 | + * @param supportFragment 要跳往的Fragment(继承自supportFragment) | |
31 | + */ | |
32 | + void startNewFragment(@NonNull SupportFragment supportFragment); | |
33 | + | |
34 | + /** | |
35 | + * 跳往新的Fragment,并出栈当前fragment | |
36 | + * | |
37 | + * @param supportFragment 要跳往的Fragment(继承自supportFragment) | |
38 | + */ | |
39 | + void startNewFragmentWithPop(@NonNull SupportFragment supportFragment); | |
40 | + | |
41 | + /** | |
42 | + * 跳往新的Fragment | |
43 | + * | |
44 | + * @param supportFragment 要跳往的Fragment(继承自supportFragment) | |
45 | + * @param requestCode requestCode | |
46 | + */ | |
47 | + void startNewFragmentForResult(@NonNull SupportFragment supportFragment, int requestCode); | |
48 | + | |
49 | + /** | |
50 | + * 设置Fragment返回Result | |
51 | + * | |
52 | + * @param resultCode resultCode | |
53 | + * @param data result data | |
54 | + */ | |
55 | + void setOnFragmentResult(int resultCode, Bundle data); | |
56 | + | |
57 | + /** | |
58 | + * 跳往新的Activity | |
59 | + * | |
60 | + * @param clz 要跳往的Activity | |
61 | + */ | |
62 | + void startNewActivity(@NonNull Class<?> clz); | |
63 | + | |
64 | + /** | |
65 | + * 跳往新的Activity | |
66 | + * | |
67 | + * @param clz 要跳往的Activity | |
68 | + * @param bundle 携带的bundle数据 | |
69 | + */ | |
70 | + void startNewActivity(@NonNull Class<?> clz, Bundle bundle); | |
71 | + | |
72 | + /** | |
73 | + * 跳往新的Activity | |
74 | + * | |
75 | + * @param clz 要跳转的Activity | |
76 | + * @param bundle bundel数据 | |
77 | + * @param requestCode requestCode | |
78 | + */ | |
79 | + void startNewActivityForResult(@NonNull Class<?> clz, Bundle bundle, int requestCode); | |
80 | + | |
81 | + /** | |
82 | + * 返回当前fragment是否可见 | |
83 | + * @return 当前fragment是否可见 | |
84 | + */ | |
85 | + boolean isVisiable(); | |
86 | + | |
87 | + /** | |
88 | + * 返回当前fragment绑定的activity | |
89 | + * @return activity | |
90 | + */ | |
91 | + Activity getBindActivity(); | |
92 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/IBaseModel.java
0 → 100644
mvpsdk/src/main/java/com/share/mvpsdk/base/IBaseView.java
0 → 100644
... | ... | @@ -0,0 +1,47 @@ |
1 | +package com.share.mvpsdk.base; | |
2 | + | |
3 | +import android.support.annotation.NonNull; | |
4 | + | |
5 | +/** | |
6 | + * Created by Horrarndoo on 2017/5/2. | |
7 | + * fragment base view接口 | |
8 | + */ | |
9 | + | |
10 | +public interface IBaseView { | |
11 | + /** | |
12 | + * 初始化presenter | |
13 | + * <p> | |
14 | + * 此方法返回的presenter对象不可为空 | |
15 | + */ | |
16 | + @NonNull | |
17 | + BasePresenter initPresenter(); | |
18 | + | |
19 | + /** | |
20 | + * 显示toast消息 | |
21 | + * | |
22 | + * @param msg 要显示的toast消息字符串 | |
23 | + */ | |
24 | + void showToast(String msg); | |
25 | + | |
26 | + /** | |
27 | + * 显示等待dialog | |
28 | + * | |
29 | + * @param waitMsg 等待消息字符串 | |
30 | + */ | |
31 | + void showWaitDialog(String waitMsg); | |
32 | + | |
33 | + /** | |
34 | + * 隐藏等待dialog | |
35 | + */ | |
36 | + void hideWaitDialog(); | |
37 | + | |
38 | + /** | |
39 | + * 隐藏键盘 | |
40 | + */ | |
41 | + void hideKeybord(); | |
42 | + | |
43 | + /** | |
44 | + * 回退 | |
45 | + */ | |
46 | + void back(); | |
47 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/activity/BaseCompatActivity.java
0 → 100644
... | ... | @@ -0,0 +1,250 @@ |
1 | +package com.share.mvpsdk.base.activity; | |
2 | + | |
3 | +import android.content.Context; | |
4 | +import android.content.Intent; | |
5 | +import android.content.pm.ActivityInfo; | |
6 | +import android.os.Bundle; | |
7 | +import android.support.v7.app.AppCompatDelegate; | |
8 | +import android.support.v7.widget.Toolbar; | |
9 | +import android.view.View; | |
10 | +import android.view.inputmethod.InputMethodManager; | |
11 | + | |
12 | + | |
13 | +import com.share.mvpsdk.AppManager; | |
14 | +import com.share.mvpsdk.R; | |
15 | +import com.share.mvpsdk.global.GlobalApplication; | |
16 | +import com.share.mvpsdk.utils.AppUtils; | |
17 | +import com.share.mvpsdk.utils.SpUtils; | |
18 | +import com.share.mvpsdk.utils.StatusBarUtils; | |
19 | +import com.share.mvpsdk.utils.ThemeUtils; | |
20 | +import com.share.mvpsdk.widgets.WaitPorgressDialog; | |
21 | + | |
22 | +import butterknife.ButterKnife; | |
23 | +import me.yokeyword.fragmentation.SupportActivity; | |
24 | +import me.yokeyword.fragmentation.anim.DefaultVerticalAnimator; | |
25 | +import me.yokeyword.fragmentation.anim.FragmentAnimator; | |
26 | + | |
27 | +/** | |
28 | + * Created by Horrarndoo on 2017/9/7. | |
29 | + * <p> | |
30 | + * BaseActivity | |
31 | + */ | |
32 | + | |
33 | +public abstract class BaseCompatActivity extends SupportActivity { | |
34 | + protected GlobalApplication mApplication; | |
35 | + protected WaitPorgressDialog mWaitPorgressDialog; | |
36 | + protected Context mContext;//全局上下文对象 | |
37 | + protected boolean isTransAnim; | |
38 | + | |
39 | + static { | |
40 | + //5.0以下兼容vector | |
41 | + AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); | |
42 | + } | |
43 | + | |
44 | + @Override | |
45 | + protected void onCreate(Bundle savedInstanceState) { | |
46 | + super.onCreate(savedInstanceState); | |
47 | + init(savedInstanceState); | |
48 | + } | |
49 | + | |
50 | + @Override | |
51 | + protected void onDestroy() { | |
52 | + super.onDestroy(); | |
53 | + AppManager.getAppManager().finishActivity(this); | |
54 | + } | |
55 | + | |
56 | + @Override | |
57 | + public FragmentAnimator onCreateFragmentAnimator() { | |
58 | + //fragment切换使用默认Vertical动画 | |
59 | + return new DefaultVerticalAnimator(); | |
60 | + } | |
61 | + | |
62 | + private void init(Bundle savedInstanceState) { | |
63 | + setTheme(ThemeUtils.themeArr[SpUtils.getThemeIndex(this)][ | |
64 | + SpUtils.getNightModel(this) ? 1 : 0]); | |
65 | + setContentView(getLayoutId()); | |
66 | + ButterKnife.bind(this); | |
67 | +// StatusBarUtils.setTransparent(this); | |
68 | + StatusBarUtils.setBarColor(this,getResources().getColor(R.color.titleColor)); | |
69 | + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); | |
70 | + initData(); | |
71 | + initView(savedInstanceState); | |
72 | + AppManager.getAppManager().addActivity(this); | |
73 | + } | |
74 | + | |
75 | + public void reload() { | |
76 | + Intent intent = getIntent(); | |
77 | + overridePendingTransition(0, 0); | |
78 | + intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); | |
79 | + finish(); | |
80 | + overridePendingTransition(0, 0); | |
81 | + startActivity(intent); | |
82 | + } | |
83 | + | |
84 | + /** | |
85 | + * 初始化数据 | |
86 | + * <p> | |
87 | + * 子类可以复写此方法初始化子类数据 | |
88 | + */ | |
89 | + protected void initData() { | |
90 | + mContext = AppUtils.getContext(); | |
91 | + mApplication = GlobalApplication.getInstance(); | |
92 | + mWaitPorgressDialog = new WaitPorgressDialog(this); | |
93 | + isTransAnim = true; | |
94 | + } | |
95 | + | |
96 | + /** | |
97 | + * 初始化view | |
98 | + * <p> | |
99 | + * 子类实现 控件绑定、视图初始化等内容 | |
100 | + * | |
101 | + * @param savedInstanceState savedInstanceState | |
102 | + */ | |
103 | + protected abstract void initView(Bundle savedInstanceState); | |
104 | + | |
105 | + /** | |
106 | + * 获取当前layouty的布局ID,用于设置当前布局 | |
107 | + * <p> | |
108 | + * 交由子类实现 | |
109 | + * | |
110 | + * @return layout Id | |
111 | + */ | |
112 | + protected abstract int getLayoutId(); | |
113 | + | |
114 | + /** | |
115 | + * 显示提示框 | |
116 | + * | |
117 | + * @param msg 提示框内容字符串 | |
118 | + */ | |
119 | + protected void showProgressDialog(String msg) { | |
120 | + mWaitPorgressDialog.setMessage(msg); | |
121 | + mWaitPorgressDialog.show(); | |
122 | + } | |
123 | + | |
124 | + /** | |
125 | + * 隐藏提示框 | |
126 | + */ | |
127 | + protected void hideProgressDialog() { | |
128 | + if (mWaitPorgressDialog != null) { | |
129 | + mWaitPorgressDialog.dismiss(); | |
130 | + } | |
131 | + } | |
132 | + | |
133 | + /** | |
134 | + * [页面跳转] | |
135 | + * | |
136 | + * @param clz 要跳转的Activity | |
137 | + */ | |
138 | + public void startActivity(Class<?> clz) { | |
139 | + startActivity(new Intent(this, clz)); | |
140 | + if (isTransAnim) | |
141 | + overridePendingTransition(R.anim.activity_start_zoom_in, R.anim | |
142 | + .activity_start_zoom_out); | |
143 | + } | |
144 | + | |
145 | + /** | |
146 | + * [页面跳转] | |
147 | + * | |
148 | + * @param clz 要跳转的Activity | |
149 | + * @param intent intent | |
150 | + */ | |
151 | + public void startActivity(Class<?> clz, Intent intent) { | |
152 | + intent.setClass(this, clz); | |
153 | + startActivity(intent); | |
154 | + if (isTransAnim) | |
155 | + overridePendingTransition(R.anim.activity_start_zoom_in, R.anim | |
156 | + .activity_start_zoom_out); | |
157 | + } | |
158 | + | |
159 | + /** | |
160 | + * [携带数据的页面跳转] | |
161 | + * | |
162 | + * @param clz 要跳转的Activity | |
163 | + * @param bundle bundel数据 | |
164 | + */ | |
165 | + public void startActivity(Class<?> clz, Bundle bundle) { | |
166 | + Intent intent = new Intent(); | |
167 | + intent.setClass(this, clz); | |
168 | + if (bundle != null) { | |
169 | + intent.putExtras(bundle); | |
170 | + } | |
171 | + startActivity(intent); | |
172 | + if (isTransAnim) | |
173 | + overridePendingTransition(R.anim.activity_start_zoom_in, R.anim | |
174 | + .activity_start_zoom_out); | |
175 | + } | |
176 | + | |
177 | + /** | |
178 | + * [含有Bundle通过Class打开编辑界面] | |
179 | + * | |
180 | + * @param clz 要跳转的Activity | |
181 | + * @param bundle bundel数据 | |
182 | + * @param requestCode requestCode | |
183 | + */ | |
184 | + public void startActivityForResult(Class<?> clz, Bundle bundle, | |
185 | + int requestCode) { | |
186 | + Intent intent = new Intent(); | |
187 | + intent.setClass(this, clz); | |
188 | + if (bundle != null) { | |
189 | + intent.putExtras(bundle); | |
190 | + } | |
191 | + startActivityForResult(intent, requestCode); | |
192 | + if (isTransAnim) | |
193 | + overridePendingTransition(R.anim.activity_start_zoom_in, R.anim | |
194 | + .activity_start_zoom_out); | |
195 | + } | |
196 | + | |
197 | + @Override | |
198 | + public void finish() { | |
199 | + super.finish(); | |
200 | + if (isTransAnim) | |
201 | + overridePendingTransition(R.anim.activity_finish_trans_in, R.anim | |
202 | + .activity_finish_trans_out); | |
203 | + } | |
204 | + | |
205 | + /** | |
206 | + * 隐藏键盘 | |
207 | + * | |
208 | + * @return 隐藏键盘结果 | |
209 | + * <p> | |
210 | + * true:隐藏成功 | |
211 | + * <p> | |
212 | + * false:隐藏失败 | |
213 | + */ | |
214 | + protected boolean hiddenKeyboard() { | |
215 | + //点击空白位置 隐藏软键盘 | |
216 | + InputMethodManager mInputMethodManager = (InputMethodManager) getSystemService | |
217 | + (INPUT_METHOD_SERVICE); | |
218 | + return mInputMethodManager.hideSoftInputFromWindow(this | |
219 | + .getCurrentFocus().getWindowToken(), 0); | |
220 | + } | |
221 | + | |
222 | + protected void initTitleBar(Toolbar toolbar, String title) { | |
223 | + toolbar.setTitle(title); | |
224 | + setSupportActionBar(toolbar); | |
225 | + getSupportActionBar().setDisplayHomeAsUpEnabled(true); | |
226 | + getSupportActionBar().setDisplayShowHomeEnabled(true); | |
227 | + toolbar.setNavigationIcon(R.mipmap.ic_arrow_back_white); | |
228 | + toolbar.setNavigationOnClickListener(new View.OnClickListener() { | |
229 | + @Override | |
230 | + public void onClick(View view) { | |
231 | + onBackPressedSupport(); | |
232 | + } | |
233 | + }); | |
234 | + } | |
235 | + | |
236 | + /** | |
237 | + * 是否使用overridePendingTransition过度动画 | |
238 | + * @return 是否使用overridePendingTransition过度动画,默认使用 | |
239 | + */ | |
240 | + protected boolean isTransAnim() { | |
241 | + return isTransAnim; | |
242 | + } | |
243 | + | |
244 | + /** | |
245 | + * 设置是否使用overridePendingTransition过度动画 | |
246 | + */ | |
247 | + protected void setIsTransAnim(boolean b){ | |
248 | + isTransAnim = b; | |
249 | + } | |
250 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/activity/BaseMVPCompatActivity.java
0 → 100644
... | ... | @@ -0,0 +1,94 @@ |
1 | +package com.share.mvpsdk.base.activity; | |
2 | + | |
3 | +import android.os.Bundle; | |
4 | +import android.support.annotation.NonNull; | |
5 | + | |
6 | +import com.share.mvpsdk.base.BasePresenter; | |
7 | +import com.share.mvpsdk.base.IBaseActivity; | |
8 | +import com.share.mvpsdk.base.IBaseModel; | |
9 | +import com.share.mvpsdk.utils.ToastUtils; | |
10 | + | |
11 | + | |
12 | +/** | |
13 | + * Created by Horrarndoo on 2017/4/6. | |
14 | + * <p> | |
15 | + * Mvp Activity基类 | |
16 | + */ | |
17 | +public abstract class BaseMVPCompatActivity<P extends BasePresenter, M extends IBaseModel> extends | |
18 | + BaseCompatActivity implements IBaseActivity { | |
19 | + /** | |
20 | + * presenter 具体的presenter由子类确定 | |
21 | + */ | |
22 | + protected P mPresenter; | |
23 | + | |
24 | + /** | |
25 | + * model 具体的model由子类确定 | |
26 | + */ | |
27 | + private M mIMode; | |
28 | + | |
29 | + /** | |
30 | + * 初始化数据 | |
31 | + * <p> | |
32 | + * 子类可以复写此方法初始化子类数据 | |
33 | + */ | |
34 | + protected void initData() { | |
35 | + super.initData(); | |
36 | + mPresenter = (P) initPresenter(); | |
37 | + if (mPresenter != null) { | |
38 | + mIMode = (M) mPresenter.getModel(); | |
39 | + if (mIMode != null) { | |
40 | + mPresenter.attachMV(mIMode, this); | |
41 | + } | |
42 | + //Logger.d("attach M V success."); | |
43 | + } | |
44 | + } | |
45 | + | |
46 | + @Override | |
47 | + protected void onDestroy() { | |
48 | + super.onDestroy(); | |
49 | + if (mPresenter != null) { | |
50 | + mPresenter.detachMV(); | |
51 | + //Logger.d("detach M V success."); | |
52 | + } | |
53 | + } | |
54 | + | |
55 | + @Override | |
56 | + public void showWaitDialog(String msg) { | |
57 | + showProgressDialog(msg); | |
58 | + } | |
59 | + | |
60 | + @Override | |
61 | + public void hideWaitDialog() { | |
62 | + hideProgressDialog(); | |
63 | + } | |
64 | + | |
65 | + @Override | |
66 | + public void showToast(String msg) { | |
67 | + ToastUtils.showToast(msg); | |
68 | + } | |
69 | + | |
70 | + @Override | |
71 | + public void startNewActivity(@NonNull Class<?> clz) { | |
72 | + startActivity(clz); | |
73 | + } | |
74 | + | |
75 | + @Override | |
76 | + public void startNewActivity(@NonNull Class<?> clz, Bundle bundle) { | |
77 | + startActivity(clz, bundle); | |
78 | + } | |
79 | + | |
80 | + @Override | |
81 | + public void startNewActivityForResult(@NonNull Class<?> clz, Bundle bundle, int requestCode) { | |
82 | + startActivityForResult(clz, bundle, requestCode); | |
83 | + } | |
84 | + | |
85 | + @Override | |
86 | + public void hideKeybord() { | |
87 | + hiddenKeyboard(); | |
88 | + } | |
89 | + | |
90 | + @Override | |
91 | + public void back() { | |
92 | + super.onBackPressedSupport(); | |
93 | + } | |
94 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/adapter/BaseRecyclerViewAdapter.java
0 → 100644
... | ... | @@ -0,0 +1,79 @@ |
1 | +package com.share.mvpsdk.base.adapter; | |
2 | + | |
3 | +import android.support.v7.widget.RecyclerView; | |
4 | +import android.view.ViewGroup; | |
5 | + | |
6 | + | |
7 | +import java.util.ArrayList; | |
8 | +import java.util.List; | |
9 | + | |
10 | +/** | |
11 | + * Created by ToaHanDong on 2017/3/23. | |
12 | + */ | |
13 | + | |
14 | +public abstract class BaseRecyclerViewAdapter<T> extends RecyclerView.Adapter<BaseRecyclerViewHolder> { | |
15 | + | |
16 | + private List<T> data = new ArrayList<>(); | |
17 | + public OnItemClickListener onItemClickListener; | |
18 | + public OnItemLongClickListener onItemLongClickListener; | |
19 | + | |
20 | + @Override | |
21 | + public BaseRecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | |
22 | + return null; | |
23 | + } | |
24 | + | |
25 | + @Override | |
26 | + public void onBindViewHolder(BaseRecyclerViewHolder holder, int position) { | |
27 | + holder.onBindViewHolder(data.get(getPosition(position)), getPosition(position)); | |
28 | + } | |
29 | + | |
30 | + | |
31 | + @Override | |
32 | + public int getItemCount() { | |
33 | + return data.size(); | |
34 | + } | |
35 | + | |
36 | + public void addAll(List<T> data) { | |
37 | + removeAll(); | |
38 | + if (data!=null) | |
39 | + this.data.addAll(data); | |
40 | + notifyDataSetChanged(); | |
41 | + } | |
42 | + | |
43 | + public void removeAll() { | |
44 | + data.clear(); | |
45 | + } | |
46 | + | |
47 | + public void remove(int position) { | |
48 | + data.remove(position); | |
49 | + } | |
50 | + | |
51 | + public void notift() { | |
52 | + notifyDataSetChanged(); | |
53 | + } | |
54 | + | |
55 | + public void remove(T object) { | |
56 | + data.remove(object); | |
57 | + } | |
58 | + | |
59 | + public List<T> getData() { | |
60 | + return data; | |
61 | + } | |
62 | + | |
63 | + public void setOnItemClickListener(OnItemClickListener onItemClickListener) { | |
64 | + this.onItemClickListener = onItemClickListener; | |
65 | + } | |
66 | + | |
67 | + public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) { | |
68 | + this.onItemLongClickListener = onItemLongClickListener; | |
69 | + } | |
70 | + | |
71 | + private int getPosition(int position) { | |
72 | + return position; | |
73 | +// if (data.size() <= 9) { | |
74 | +// return position; | |
75 | +// } | |
76 | +// return position % (data.size()); | |
77 | + } | |
78 | + | |
79 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/adapter/BaseRecyclerViewHolder.java
0 → 100644
... | ... | @@ -0,0 +1,22 @@ |
1 | +package com.share.mvpsdk.base.adapter; | |
2 | + | |
3 | +import android.support.v7.widget.RecyclerView; | |
4 | +import android.view.View; | |
5 | + | |
6 | +/** | |
7 | + * Created by ToaHanDong on 2017/3/23. | |
8 | + */ | |
9 | + | |
10 | +public abstract class BaseRecyclerViewHolder<T> extends RecyclerView.ViewHolder { | |
11 | + | |
12 | + public BaseRecyclerViewHolder(View itemView) { | |
13 | + super(itemView); | |
14 | + } | |
15 | + | |
16 | + public abstract void onBindViewHolder(T object, final int position); | |
17 | + | |
18 | + void OnBaseBindViewHolder(T Object,int position){ | |
19 | + onBindViewHolder(Object,position); | |
20 | + } | |
21 | + | |
22 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/adapter/OnItemClickListener.java
0 → 100644
mvpsdk/src/main/java/com/share/mvpsdk/base/adapter/OnItemLongClickListener.java
0 → 100644
mvpsdk/src/main/java/com/share/mvpsdk/base/entity/BaseEntity.java
0 → 100644
... | ... | @@ -0,0 +1,47 @@ |
1 | +package com.share.mvpsdk.base.entity; | |
2 | + | |
3 | +import java.io.Serializable; | |
4 | + | |
5 | +/** | |
6 | + * Created by ToaHanDong on 2017/4/27. | |
7 | + */ | |
8 | + | |
9 | +public class BaseEntity<T> implements Serializable { | |
10 | + | |
11 | + private int status; | |
12 | + private String message; | |
13 | + private T data; | |
14 | + | |
15 | + public int getStatus() { | |
16 | + return status; | |
17 | + } | |
18 | + | |
19 | + public void setStatus(int status) { | |
20 | + this.status = status; | |
21 | + } | |
22 | + | |
23 | + public String getMessage() { | |
24 | + return message; | |
25 | + } | |
26 | + | |
27 | + public void setMessage(String message) { | |
28 | + this.message = message; | |
29 | + } | |
30 | + | |
31 | + public T getData() { | |
32 | + return data; | |
33 | + } | |
34 | + | |
35 | + public void setData(T data) { | |
36 | + this.data = data; | |
37 | + } | |
38 | + | |
39 | + @Override | |
40 | + public String toString() { | |
41 | + return "BaseEntity{" + | |
42 | + "status=" + status + | |
43 | + ", message='" + message + '\'' + | |
44 | + ", data=" + data + | |
45 | + '}'; | |
46 | + } | |
47 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/entity/BaseListEntity.java
0 → 100644
... | ... | @@ -0,0 +1,48 @@ |
1 | +package com.share.mvpsdk.base.entity; | |
2 | + | |
3 | +import java.io.Serializable; | |
4 | +import java.util.List; | |
5 | + | |
6 | +/** | |
7 | + * Created by ToaHanDong on 2017/6/6. | |
8 | + */ | |
9 | + | |
10 | +public class BaseListEntity<T> implements Serializable { | |
11 | + | |
12 | + private int status; | |
13 | + private String message; | |
14 | + private List<T> data; | |
15 | + | |
16 | + public int getStatus() { | |
17 | + return status; | |
18 | + } | |
19 | + | |
20 | + public void setStatus(int status) { | |
21 | + this.status = status; | |
22 | + } | |
23 | + | |
24 | + public String getMessage() { | |
25 | + return message; | |
26 | + } | |
27 | + | |
28 | + public void setMessage(String message) { | |
29 | + this.message = message; | |
30 | + } | |
31 | + | |
32 | + public List<T> getData() { | |
33 | + return data; | |
34 | + } | |
35 | + | |
36 | + public void setData(List<T> data) { | |
37 | + this.data = data; | |
38 | + } | |
39 | + | |
40 | + @Override | |
41 | + public String toString() { | |
42 | + return "BaseListEntity{" + | |
43 | + "status=" + status + | |
44 | + ", message='" + message + '\'' + | |
45 | + ", data=" + data + | |
46 | + '}'; | |
47 | + } | |
48 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/fragment/BaseCompatFragment.java
0 → 100644
... | ... | @@ -0,0 +1,153 @@ |
1 | +package com.share.mvpsdk.base.fragment; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | +import android.content.Context; | |
5 | +import android.content.pm.ActivityInfo; | |
6 | +import android.os.Bundle; | |
7 | +import android.support.annotation.LayoutRes; | |
8 | +import android.support.annotation.Nullable; | |
9 | +import android.util.Log; | |
10 | +import android.view.LayoutInflater; | |
11 | +import android.view.View; | |
12 | +import android.view.ViewGroup; | |
13 | + | |
14 | + | |
15 | +import com.share.mvpsdk.global.GlobalApplication; | |
16 | +import com.share.mvpsdk.utils.AppUtils; | |
17 | +import com.share.mvpsdk.widgets.WaitPorgressDialog; | |
18 | + | |
19 | +import butterknife.ButterKnife; | |
20 | +import butterknife.Unbinder; | |
21 | +import me.yokeyword.fragmentation.SupportFragment; | |
22 | +import timber.log.Timber; | |
23 | + | |
24 | +/** | |
25 | + * Created by Horrarndoo on 2017/9/26. | |
26 | + * <p> | |
27 | + */ | |
28 | + | |
29 | +public abstract class BaseCompatFragment extends SupportFragment { | |
30 | + | |
31 | + protected String TAG; | |
32 | + protected Context mContext; | |
33 | + protected Activity mActivity; | |
34 | + protected GlobalApplication mApplication; | |
35 | + protected WaitPorgressDialog mWaitPorgressDialog; | |
36 | +// private Unbinder binder; | |
37 | + | |
38 | + @Override | |
39 | + public void onAttach(Context context) { | |
40 | + mActivity = (Activity) context; | |
41 | + mContext = context; | |
42 | + super.onAttach(context); | |
43 | + } | |
44 | + | |
45 | + @Override | |
46 | + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable | |
47 | + Bundle savedInstanceState) { | |
48 | + if (getLayoutView() != null) { | |
49 | + return getLayoutView(); | |
50 | + } else { | |
51 | + // return inflater.inflate(getLayoutId(), null); | |
52 | + return inflater.inflate(getLayoutId(), container, false); | |
53 | + } | |
54 | + } | |
55 | + | |
56 | + @Override | |
57 | + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { | |
58 | + ButterKnife.bind(this, view); | |
59 | + super.onViewCreated(view, savedInstanceState); | |
60 | + mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); | |
61 | + TAG = getClass().getSimpleName(); | |
62 | + getBundle(getArguments()); | |
63 | + initData(); | |
64 | + initUI(view, savedInstanceState); | |
65 | + } | |
66 | + | |
67 | + | |
68 | + @Override | |
69 | + public void onDestroyView() { | |
70 | + super.onDestroyView(); | |
71 | +// if (binder != null) | |
72 | +// binder.unbind(); | |
73 | + } | |
74 | + | |
75 | + @Override | |
76 | + public void onDetach() { | |
77 | + super.onDetach(); | |
78 | + } | |
79 | + | |
80 | + @Override | |
81 | + public void onDestroy() { | |
82 | + super.onDestroy(); | |
83 | + } | |
84 | + | |
85 | + @LayoutRes | |
86 | + public abstract int getLayoutId(); | |
87 | + | |
88 | + public View getLayoutView() { | |
89 | + return null; | |
90 | + } | |
91 | + | |
92 | + /** | |
93 | + * 得到Activity传进来的值 | |
94 | + */ | |
95 | + public void getBundle(Bundle bundle) { | |
96 | + } | |
97 | + | |
98 | + /** | |
99 | + * 初始化UI | |
100 | + */ | |
101 | + public abstract void initUI(View view, @Nullable Bundle savedInstanceState); | |
102 | + | |
103 | + /** | |
104 | + * 在监听器之前把数据准备好 | |
105 | + */ | |
106 | + public void initData() { | |
107 | + mWaitPorgressDialog = new WaitPorgressDialog(mActivity); | |
108 | + mContext = AppUtils.getContext(); | |
109 | + mApplication = GlobalApplication.getInstance(); | |
110 | + } | |
111 | + | |
112 | + /** | |
113 | + * 处理回退事件 | |
114 | + * | |
115 | + * @return true 事件已消费 | |
116 | + * <p> | |
117 | + * false 事件向上传递 | |
118 | + */ | |
119 | + @Override | |
120 | + public boolean onBackPressedSupport() { | |
121 | + if (getFragmentManager().getBackStackEntryCount() > 1) { | |
122 | + //如果当前存在fragment>1,当前fragment出栈 | |
123 | + pop(); | |
124 | + } else { | |
125 | + //已经退栈到root fragment,交由Activity处理回退事件 | |
126 | + return false; | |
127 | + } | |
128 | + return true; | |
129 | + } | |
130 | + | |
131 | + /** | |
132 | + * 显示提示框 | |
133 | + * | |
134 | + * @param msg 提示框内容字符串 | |
135 | + */ | |
136 | + protected void showProgressDialog(String msg) { | |
137 | + if (mWaitPorgressDialog.isShowing()) { | |
138 | + mWaitPorgressDialog.dismiss(); | |
139 | + } | |
140 | + | |
141 | + mWaitPorgressDialog.setMessage(msg); | |
142 | + mWaitPorgressDialog.show(); | |
143 | + } | |
144 | + | |
145 | + /** | |
146 | + * 隐藏提示框 | |
147 | + */ | |
148 | + protected void hideProgressDialog() { | |
149 | + if (mWaitPorgressDialog != null) { | |
150 | + mWaitPorgressDialog.dismiss(); | |
151 | + } | |
152 | + } | |
153 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/fragment/BaseMVPCompatFragment.java
0 → 100644
... | ... | @@ -0,0 +1,128 @@ |
1 | +package com.share.mvpsdk.base.fragment; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | +import android.os.Bundle; | |
5 | +import android.support.annotation.NonNull; | |
6 | +import android.widget.Toast; | |
7 | + | |
8 | + | |
9 | +import com.share.mvpsdk.base.BasePresenter; | |
10 | +import com.share.mvpsdk.base.IBaseFragment; | |
11 | +import com.share.mvpsdk.base.IBaseModel; | |
12 | +import com.share.mvpsdk.base.activity.BaseCompatActivity; | |
13 | +import com.share.mvpsdk.utils.ToastUtils; | |
14 | + | |
15 | +import me.yokeyword.fragmentation.SupportFragment; | |
16 | + | |
17 | +/** | |
18 | + * Created by Horrarndoo on 2017/9/6. | |
19 | + * <p> | |
20 | + * Mvp Fragment基类 | |
21 | + * <p> | |
22 | + * 实现IBaseView方法、绑定butterknife | |
23 | + */ | |
24 | + | |
25 | +public abstract class BaseMVPCompatFragment<P extends BasePresenter, M extends IBaseModel> extends | |
26 | + BaseCompatFragment implements IBaseFragment { | |
27 | + public P mPresenter; | |
28 | + public M mIMode; | |
29 | + | |
30 | + /** | |
31 | + * 在监听器之前把数据准备好 | |
32 | + */ | |
33 | + public void initData() { | |
34 | + super.initData(); | |
35 | + | |
36 | + mPresenter = (P) initPresenter(); | |
37 | + if (mPresenter != null) { | |
38 | + mIMode = (M) mPresenter.getModel(); | |
39 | + if (mIMode != null) { | |
40 | + mPresenter.attachMV(mIMode, this); | |
41 | + } | |
42 | + } | |
43 | + } | |
44 | + | |
45 | + @Override | |
46 | + public void onDestroy() { | |
47 | + super.onDestroy(); | |
48 | + if (mPresenter != null) { | |
49 | + mPresenter.detachMV(); | |
50 | + } | |
51 | + } | |
52 | + | |
53 | + @Override | |
54 | + public void showWaitDialog(String msg) { | |
55 | + showProgressDialog(msg); | |
56 | + } | |
57 | + | |
58 | + @Override | |
59 | + public void hideWaitDialog() { | |
60 | + hideProgressDialog(); | |
61 | + } | |
62 | + | |
63 | + @Override | |
64 | + public void showToast(String msg) { | |
65 | + ToastUtils.showToast(mContext, msg, Toast.LENGTH_SHORT); | |
66 | + } | |
67 | + | |
68 | + @Override | |
69 | + public void back() { | |
70 | + this.onBackPressedSupport(); | |
71 | + } | |
72 | + | |
73 | + @Override | |
74 | + public void startNewFragment(@NonNull SupportFragment supportFragment) { | |
75 | + start(supportFragment); | |
76 | + } | |
77 | + | |
78 | + @Override | |
79 | + public void startNewFragmentWithPop(@NonNull SupportFragment supportFragment) { | |
80 | + startWithPop(supportFragment); | |
81 | + } | |
82 | + | |
83 | + @Override | |
84 | + public void startNewFragmentForResult(@NonNull SupportFragment supportFragment, int | |
85 | + requestCode) { | |
86 | + startForResult(supportFragment, requestCode); | |
87 | + } | |
88 | + | |
89 | + @Override | |
90 | + public void popToFragment(Class<?> targetFragmentClass, boolean includeTargetFragment) { | |
91 | + popTo(targetFragmentClass, includeTargetFragment); | |
92 | + } | |
93 | + | |
94 | + @Override | |
95 | + public void hideKeybord() { | |
96 | + hideSoftInput(); | |
97 | + } | |
98 | + | |
99 | + @Override | |
100 | + public void setOnFragmentResult(int ResultCode, Bundle data) { | |
101 | + setFragmentResult(ResultCode, data); | |
102 | + } | |
103 | + | |
104 | + @Override | |
105 | + public void startNewActivity(@NonNull Class<?> clz) { | |
106 | + ((BaseCompatActivity) mActivity).startActivity(clz); | |
107 | + } | |
108 | + | |
109 | + @Override | |
110 | + public void startNewActivity(@NonNull Class<?> clz, Bundle bundle) { | |
111 | + ((BaseCompatActivity) mActivity).startActivity(clz, bundle); | |
112 | + } | |
113 | + | |
114 | + @Override | |
115 | + public void startNewActivityForResult(@NonNull Class<?> clz, Bundle bundle, int requestCode) { | |
116 | + ((BaseCompatActivity) mActivity).startActivityForResult(clz, bundle, requestCode); | |
117 | + } | |
118 | + | |
119 | + @Override | |
120 | + public boolean isVisiable() { | |
121 | + return isSupportVisible(); | |
122 | + } | |
123 | + | |
124 | + @Override | |
125 | + public Activity getBindActivity() { | |
126 | + return mActivity; | |
127 | + } | |
128 | +} | |
0 | 129 | \ No newline at end of file | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/base/fragment/BaseRecycleFragment.java
0 → 100644
... | ... | @@ -0,0 +1,68 @@ |
1 | +package com.share.mvpsdk.base.fragment; | |
2 | + | |
3 | +import android.os.Bundle; | |
4 | +import android.support.annotation.Nullable; | |
5 | +import android.view.LayoutInflater; | |
6 | +import android.view.View; | |
7 | +import android.view.ViewGroup; | |
8 | + | |
9 | +import com.share.mvpsdk.R; | |
10 | +import com.share.mvpsdk.base.BasePresenter; | |
11 | +import com.share.mvpsdk.base.IBaseModel; | |
12 | + | |
13 | + | |
14 | +/** | |
15 | + * Created by Horrarndoo on 2017/10/17. | |
16 | + * <p> | |
17 | + * 带RecycleView加载状态view的fragment,主要用于显示加载中、空界面、加载失败等状态界面显示 | |
18 | + */ | |
19 | + | |
20 | +public abstract class BaseRecycleFragment<P extends BasePresenter, M extends IBaseModel> extends | |
21 | + BaseMVPCompatFragment<P, M> { | |
22 | + /** | |
23 | + * 网络异常View | |
24 | + */ | |
25 | + protected View errorView; | |
26 | + /** | |
27 | + * loadingView | |
28 | + */ | |
29 | + protected View loadingView; | |
30 | + /** | |
31 | + * 没有内容view | |
32 | + */ | |
33 | + protected View emptyView; | |
34 | + | |
35 | + @Override | |
36 | + public void onLazyInitView(@Nullable Bundle savedInstanceState) { | |
37 | + super.onLazyInitView(savedInstanceState); | |
38 | + showLoading(); | |
39 | + } | |
40 | + | |
41 | + @Override | |
42 | + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable | |
43 | + Bundle savedInstanceState) { | |
44 | + errorView = inflater.inflate(R.layout.view_network_error, container, false); | |
45 | + loadingView = inflater.inflate(R.layout.view_loading, container, false); | |
46 | + emptyView = inflater.inflate(R.layout.view_empty, container, false); | |
47 | + errorView.setOnClickListener(new View.OnClickListener() { | |
48 | + @Override | |
49 | + public void onClick(View v) { | |
50 | + showLoading(); | |
51 | + onErrorViewClick(v); | |
52 | + } | |
53 | + }); | |
54 | + return super.onCreateView(inflater, container, savedInstanceState); | |
55 | + } | |
56 | + | |
57 | + /** | |
58 | + * 网络异常view被点击时触发,由子类实现 | |
59 | + * | |
60 | + * @param view view | |
61 | + */ | |
62 | + protected abstract void onErrorViewClick(View view); | |
63 | + | |
64 | + /** | |
65 | + * 显示加载中view,由子类实现 | |
66 | + */ | |
67 | + protected abstract void showLoading(); | |
68 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/config/DBConfig.java
0 → 100644
... | ... | @@ -0,0 +1,16 @@ |
1 | +package com.share.mvpsdk.config; | |
2 | + | |
3 | +/** | |
4 | + * Created by Horrarndoo on 2017/9/13. | |
5 | + * <p> | |
6 | + * 数据库全局常量 | |
7 | + */ | |
8 | + | |
9 | +public class DBConfig { | |
10 | + public static final String DB_NAME = "db_name_yizhi"; | |
11 | + public static final String TABLE_ZHIHU = "table_zhihu"; | |
12 | + public static final String TABLE_WANGYI = "table_top_news"; | |
13 | + public static final String TABLE_WEIXIN = "table_weixin"; | |
14 | + public static final String TABLE_GANKIO_DAY = "table_gank_io_day"; | |
15 | + public static final String TABLE_GANKIO_CUSTOM = "table_gank_io_custom"; | |
16 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/config/ItemState.java
0 → 100644
... | ... | @@ -0,0 +1,19 @@ |
1 | +package com.share.mvpsdk.config; | |
2 | + | |
3 | +/** | |
4 | + * Created by Horrarndoo on 2017/9/13. | |
5 | + * <p> | |
6 | + * item状态全局常量 | |
7 | + */ | |
8 | + | |
9 | +public class ItemState { | |
10 | + /** | |
11 | + * 已读状态 | |
12 | + */ | |
13 | + public static final int STATE_IS_READ = 1; | |
14 | + | |
15 | + /** | |
16 | + * 非已读状态 | |
17 | + */ | |
18 | + public static final int STATE_IS_NO_READ = 0; | |
19 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/global/GlobalApplication.java
0 → 100644
... | ... | @@ -0,0 +1,72 @@ |
1 | +package com.share.mvpsdk.global; | |
2 | + | |
3 | +import android.app.Application; | |
4 | +import android.content.Context; | |
5 | +import android.os.Handler; | |
6 | + | |
7 | +import com.orhanobut.logger.LogLevel; | |
8 | +import com.orhanobut.logger.Logger; | |
9 | +import com.share.mvpsdk.utils.ToastUtils; | |
10 | + | |
11 | +import timber.log.BuildConfig; | |
12 | +import timber.log.Timber; | |
13 | + | |
14 | + | |
15 | +/** | |
16 | + * Created by Horrarndoo on 2017/9/1. | |
17 | + * <p> | |
18 | + * 全局Application | |
19 | + */ | |
20 | + | |
21 | +public class GlobalApplication extends Application { | |
22 | + private static final String LOG_TAG = "YZ_LOGGER"; | |
23 | + protected static Context context; | |
24 | + protected static Handler handler; | |
25 | + protected static int mainThreadId; | |
26 | + private static GlobalApplication mApp; | |
27 | + | |
28 | + public static synchronized GlobalApplication getInstance() { | |
29 | + return mApp; | |
30 | + } | |
31 | + | |
32 | + @Override | |
33 | + public void onCreate() { | |
34 | + super.onCreate(); | |
35 | + context = getApplicationContext(); | |
36 | + handler = new Handler(); | |
37 | + mainThreadId = android.os.Process.myTid(); | |
38 | + mApp=this; | |
39 | + if (!BuildConfig.DEBUG) { | |
40 | + Timber.plant(new Timber.DebugTree()); | |
41 | + } | |
42 | + //LogLevel.FULL : LogLevel.NONE | |
43 | +// Logger.init(LOG_TAG).logLevel(LogLevel.FULL); | |
44 | + } | |
45 | + | |
46 | + /** | |
47 | + * 获取上下文对象 | |
48 | + * | |
49 | + * @return context | |
50 | + */ | |
51 | + public static Context getContext() { | |
52 | + return context; | |
53 | + } | |
54 | + | |
55 | + /** | |
56 | + * 获取全局handler | |
57 | + * | |
58 | + * @return 全局handler | |
59 | + */ | |
60 | + public static Handler getHandler() { | |
61 | + return handler; | |
62 | + } | |
63 | + | |
64 | + /** | |
65 | + * 获取主线程id | |
66 | + * | |
67 | + * @return 主线程id | |
68 | + */ | |
69 | + public static int getMainThreadId() { | |
70 | + return mainThreadId; | |
71 | + } | |
72 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/helper/BottomNavigationViewHelper.java
0 → 100644
... | ... | @@ -0,0 +1,37 @@ |
1 | +package com.share.mvpsdk.helper; | |
2 | + | |
3 | +import android.support.design.internal.BottomNavigationItemView; | |
4 | +import android.support.design.internal.BottomNavigationMenuView; | |
5 | +import android.support.design.widget.BottomNavigationView; | |
6 | +import android.util.Log; | |
7 | + | |
8 | +import java.lang.reflect.Field; | |
9 | + | |
10 | +/** | |
11 | + * Created by Horrarndoo on 2017/9/22. | |
12 | + * <p> | |
13 | + * BottomNavigationView禁止3个item以上动画切换效果 | |
14 | + */ | |
15 | +public class BottomNavigationViewHelper { | |
16 | + public static void disableShiftMode(BottomNavigationView view) { | |
17 | + BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0); | |
18 | + try { | |
19 | + Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode"); | |
20 | + shiftingMode.setAccessible(true); | |
21 | + shiftingMode.setBoolean(menuView, false); | |
22 | + shiftingMode.setAccessible(false); | |
23 | + for (int i = 0; i < menuView.getChildCount(); i++) { | |
24 | + BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i); | |
25 | + //noinspection RestrictedApi | |
26 | + item.setShiftingMode(false); | |
27 | + // set once again checked value, so view will be updated | |
28 | + //noinspection RestrictedApi | |
29 | + item.setChecked(item.getItemData().isChecked()); | |
30 | + } | |
31 | + } catch (NoSuchFieldException e) { | |
32 | + Log.e("BNVHelper", "Unable to get shift mode field", e); | |
33 | + } catch (IllegalAccessException e) { | |
34 | + Log.e("BNVHelper", "Unable to change value of shift mode", e); | |
35 | + } | |
36 | + } | |
37 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/helper/RetrofitCreateHelper.java
0 → 100644
... | ... | @@ -0,0 +1,130 @@ |
1 | +package com.share.mvpsdk.helper; | |
2 | + | |
3 | + | |
4 | +import com.share.mvpsdk.helper.okhttp.CacheInterceptor; | |
5 | +import com.share.mvpsdk.utils.StringUtils; | |
6 | + | |
7 | +import java.io.IOException; | |
8 | +import java.util.concurrent.TimeUnit; | |
9 | + | |
10 | +import okhttp3.Interceptor; | |
11 | +import okhttp3.OkHttpClient; | |
12 | +import okhttp3.Request; | |
13 | +import okhttp3.Response; | |
14 | +import okhttp3.logging.HttpLoggingInterceptor; | |
15 | +import retrofit2.Retrofit; | |
16 | +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; | |
17 | +import retrofit2.converter.gson.GsonConverterFactory; | |
18 | + | |
19 | +/** | |
20 | + * Created by Horrarndoo on 2017/9/7. | |
21 | + * <p> | |
22 | + */ | |
23 | + | |
24 | +public class RetrofitCreateHelper { | |
25 | + private static final int TIMEOUT_READ = 20; | |
26 | + private static final int TIMEOUT_CONNECTION = 10; | |
27 | + private static String Authorization = "", token = ""; | |
28 | + private static RetrofitCreateHelper retrofitCreateHelper = null; | |
29 | + private static final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor() | |
30 | + .setLevel(HttpLoggingInterceptor.Level.BODY); | |
31 | + private static CacheInterceptor cacheInterceptor = new CacheInterceptor(); | |
32 | + private static OkHttpClient.Builder okhttpClientBuilder = null; | |
33 | + | |
34 | + /*private static OkHttpClient okHttpClient = new OkHttpClient.Builder() | |
35 | + //SSL证书 | |
36 | + .sslSocketFactory(TrustManager.getUnsafeOkHttpClient()) | |
37 | + .hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) | |
38 | + //打印日志 | |
39 | + .addInterceptor(interceptor) | |
40 | + //设置Cache拦截器 | |
41 | + .addNetworkInterceptor(cacheInterceptor) | |
42 | + .addInterceptor(cacheInterceptor) | |
43 | + .cache(HttpCache.getCache()) | |
44 | + //time out | |
45 | + .connectTimeout(TIMEOUT_CONNECTION, TimeUnit.SECONDS) | |
46 | + .readTimeout(TIMEOUT_READ, TimeUnit.SECONDS) | |
47 | + .writeTimeout(TIMEOUT_READ, TimeUnit.SECONDS) | |
48 | + //失败重连 | |
49 | + .retryOnConnectionFailure(true) | |
50 | + .build();*/ | |
51 | + public static RetrofitCreateHelper getInstance() { | |
52 | + if (null == retrofitCreateHelper) { | |
53 | + synchronized (RetrofitCreateHelper.class) { | |
54 | + if (null == retrofitCreateHelper) retrofitCreateHelper = new RetrofitCreateHelper(); | |
55 | + } | |
56 | + } | |
57 | + return retrofitCreateHelper; | |
58 | + } | |
59 | + | |
60 | + public RetrofitCreateHelper() { | |
61 | + try { | |
62 | + if (null == okhttpClientBuilder) { | |
63 | + okhttpClientBuilder = new OkHttpClient.Builder(); | |
64 | + okhttpClientBuilder.connectTimeout(10000, TimeUnit.SECONDS); | |
65 | + okhttpClientBuilder.addInterceptor(new Interceptor() { | |
66 | + @Override | |
67 | + public Response intercept(Chain chain) throws IOException { | |
68 | + Request original = chain.request(); | |
69 | + Request.Builder requestBuilder = original.newBuilder().header("Authorization", Authorization); | |
70 | + Request request = requestBuilder.build(); | |
71 | + return chain.proceed(request); | |
72 | + } | |
73 | + }); | |
74 | + okhttpClientBuilder.addNetworkInterceptor(cacheInterceptor); | |
75 | + okhttpClientBuilder.addInterceptor(interceptor); | |
76 | + } | |
77 | + } catch (Exception e) { | |
78 | + e.printStackTrace(); | |
79 | + } | |
80 | + } | |
81 | + | |
82 | + public <T> T createApi(Class<T> clazz, String url) { | |
83 | + Authorization = token; | |
84 | + Retrofit retrofit = new Retrofit.Builder() | |
85 | + .baseUrl(url) | |
86 | + .client(okhttpClientBuilder.build()) | |
87 | + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) | |
88 | + .addConverterFactory(GsonConverterFactory.create()) | |
89 | + .build(); | |
90 | + return retrofit.create(clazz); | |
91 | + } | |
92 | + | |
93 | + // public static <T> T loginApi(Class<T> clazz, String url) { | |
94 | +// Authorization= StringUtils.getSign(); | |
95 | +// okHttpClient.newBuilder().addInterceptor(new Interceptor() { | |
96 | +// @Override | |
97 | +// public Response intercept(Chain chain) throws IOException { | |
98 | +// Request original = chain.request(); | |
99 | +// Request.Builder requestBuilder = original.newBuilder().header("Authorization", Authorization); | |
100 | +// Request request = requestBuilder.build(); | |
101 | +// return chain.proceed(request); | |
102 | +// } | |
103 | +// }); | |
104 | +// Log.d("77777","Authorization="+Authorization); | |
105 | +// Retrofit retrofit = new Retrofit.Builder() | |
106 | +// .baseUrl(url) | |
107 | +// .client(okHttpClient) | |
108 | +// .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) | |
109 | +// .addConverterFactory(GsonConverterFactory.create()) | |
110 | +// .build(); | |
111 | +// return retrofit.create(clazz); | |
112 | +// } | |
113 | + public void setAuthorization(String Authorization) { | |
114 | + this.token ="Bearer " + Authorization; | |
115 | + } | |
116 | + | |
117 | + public <T> T login(Class<T> clazz, String url) { | |
118 | + Authorization = StringUtils.getSign(); | |
119 | + Retrofit retrofit = new Retrofit.Builder() | |
120 | + .client(okhttpClientBuilder.build()) | |
121 | + .baseUrl(url) | |
122 | + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) | |
123 | + .addConverterFactory(GsonConverterFactory.create()) | |
124 | + .build(); | |
125 | + return retrofit.create(clazz); | |
126 | + } | |
127 | + | |
128 | + | |
129 | +} | |
130 | + | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/helper/RxHelper.java
0 → 100644
... | ... | @@ -0,0 +1,76 @@ |
1 | +package com.share.mvpsdk.helper; | |
2 | + | |
3 | + | |
4 | +import io.reactivex.BackpressureStrategy; | |
5 | +import io.reactivex.Flowable; | |
6 | +import io.reactivex.FlowableEmitter; | |
7 | +import io.reactivex.FlowableOnSubscribe; | |
8 | +import io.reactivex.Observable; | |
9 | +import io.reactivex.ObservableEmitter; | |
10 | +import io.reactivex.ObservableOnSubscribe; | |
11 | +import io.reactivex.ObservableSource; | |
12 | +import io.reactivex.ObservableTransformer; | |
13 | +import io.reactivex.android.schedulers.AndroidSchedulers; | |
14 | +import io.reactivex.schedulers.Schedulers; | |
15 | + | |
16 | +/** | |
17 | + * Created by Horrarndoo on 2017/9/12. | |
18 | + * <p> | |
19 | + */ | |
20 | +public class RxHelper { | |
21 | + /** | |
22 | + * 统一线程处理 | |
23 | + * <p> | |
24 | + * 发布事件io线程,接收事件主线程 | |
25 | + */ | |
26 | + public static <T> ObservableTransformer<T, T> rxSchedulerHelper() {//compose处理线程 | |
27 | + return new ObservableTransformer<T, T>() { | |
28 | + | |
29 | + @Override | |
30 | + public ObservableSource<T> apply(Observable<T> upstream) { | |
31 | + return upstream.subscribeOn(Schedulers.io()) | |
32 | + .observeOn(AndroidSchedulers.mainThread()); | |
33 | + } | |
34 | + }; | |
35 | + } | |
36 | + | |
37 | + /** | |
38 | + * 生成Flowable | |
39 | + * | |
40 | + * @param t | |
41 | + * @return Flowable | |
42 | + */ | |
43 | + public static <T> Flowable<T> createFlowable(final T t) { | |
44 | + return Flowable.create(new FlowableOnSubscribe<T>() { | |
45 | + @Override | |
46 | + public void subscribe(FlowableEmitter<T> emitter) throws Exception { | |
47 | + try { | |
48 | + emitter.onNext(t); | |
49 | + emitter.onComplete(); | |
50 | + } catch (Exception e) { | |
51 | + emitter.onError(e); | |
52 | + } | |
53 | + } | |
54 | + }, BackpressureStrategy.BUFFER); | |
55 | + } | |
56 | + | |
57 | + /** | |
58 | + * 生成Observable | |
59 | + * | |
60 | + * @param t | |
61 | + * @return Flowable | |
62 | + */ | |
63 | + public static <T> Observable<T> createObservable(final T t) { | |
64 | + return Observable.create(new ObservableOnSubscribe<T>() { | |
65 | + @Override | |
66 | + public void subscribe(ObservableEmitter<T> emitter) throws Exception { | |
67 | + try { | |
68 | + emitter.onNext(t); | |
69 | + emitter.onComplete(); | |
70 | + } catch (Exception e) { | |
71 | + emitter.onError(e); | |
72 | + } | |
73 | + } | |
74 | + }); | |
75 | + } | |
76 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/helper/okhttp/CacheInterceptor.java
0 → 100644
... | ... | @@ -0,0 +1,84 @@ |
1 | +package com.share.mvpsdk.helper.okhttp; | |
2 | + | |
3 | + | |
4 | + | |
5 | +import com.share.mvpsdk.utils.AppUtils; | |
6 | +import com.share.mvpsdk.utils.NetworkConnectionUtils; | |
7 | + | |
8 | +import java.io.IOException; | |
9 | + | |
10 | +import okhttp3.CacheControl; | |
11 | +import okhttp3.Interceptor; | |
12 | +import okhttp3.Request; | |
13 | +import okhttp3.Response; | |
14 | + | |
15 | +import static com.share.mvpsdk.utils.HttpUtils.getUserAgent; | |
16 | + | |
17 | + | |
18 | +/** | |
19 | + * Created by Horrarndoo on 2017/9/12. | |
20 | + * <p> | |
21 | + * CacheInterceptor | |
22 | + */ | |
23 | +public class CacheInterceptor implements Interceptor { | |
24 | + | |
25 | + @Override | |
26 | + public Response intercept(Chain chain) throws IOException { | |
27 | + | |
28 | + Request request = chain.request(); | |
29 | + Response response = chain.proceed(request); | |
30 | + if (NetworkConnectionUtils.isNetworkConnected(AppUtils.getContext())) { | |
31 | + // 有网络时, 缓存1小时 | |
32 | + int maxAge = 60 * 60; | |
33 | + request = request.newBuilder() | |
34 | + .removeHeader("User-Agent") | |
35 | + .header("User-Agent", getUserAgent()) | |
36 | + .build(); | |
37 | + | |
38 | +// Response response = chain.proceed(request); | |
39 | + return response.newBuilder() | |
40 | + .removeHeader("Pragma") | |
41 | + .removeHeader("Cache-Control") | |
42 | + .header("Cache-Control", "public, max-age=" + maxAge) | |
43 | + .build(); | |
44 | + } else { | |
45 | + // 无网络时,缓存为4周 | |
46 | + int maxStale = 60 * 60 * 24 * 28; | |
47 | + request = request.newBuilder() | |
48 | + .cacheControl(CacheControl.FORCE_CACHE) | |
49 | + .removeHeader("User-Agent") | |
50 | + .header("User-Agent", getUserAgent()) | |
51 | + .build(); | |
52 | + | |
53 | + return response.newBuilder() | |
54 | + .removeHeader("Pragma") | |
55 | + .removeHeader("Cache-Control") | |
56 | + .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale) | |
57 | + .build(); | |
58 | + } | |
59 | + // Request request = chain.request(); | |
60 | + // if (!NetworkConnectionUtils.isConnected(AppUtils.getContext())) { | |
61 | + // request = request.newBuilder() | |
62 | + // .cacheControl(CacheControl.FORCE_CACHE) | |
63 | + // .build(); | |
64 | + // } | |
65 | + // Response response = chain.proceed(request); | |
66 | + // if (NetworkConnectionUtils.isConnected(AppUtils.getContext())) { | |
67 | + // int maxAge = 0; | |
68 | + // // 有网络时, 不缓存, 最大保存时长为0 | |
69 | + // response.newBuilder() | |
70 | + // .header("Cache-Control", "public, max-age=" + maxAge) | |
71 | + // .removeHeader("Pragma") | |
72 | + // .build(); | |
73 | + // } else { | |
74 | + // // 无网络时,设置超时为4周 | |
75 | + // int maxStale = 60 * 60 * 24 * 28; | |
76 | + // response.newBuilder() | |
77 | + // .header("Cache-Control", "public, only-if-cached, max-stale=" + | |
78 | + // maxStale) | |
79 | + // .removeHeader("Pragma") | |
80 | + // .build(); | |
81 | + // } | |
82 | + // return response; | |
83 | + } | |
84 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/helper/okhttp/HttpCache.java
0 → 100644
... | ... | @@ -0,0 +1,28 @@ |
1 | +package com.share.mvpsdk.helper.okhttp; | |
2 | + | |
3 | + | |
4 | +import android.os.Environment; | |
5 | + | |
6 | +import com.share.mvpsdk.utils.AppUtils; | |
7 | + | |
8 | +import java.io.File; | |
9 | + | |
10 | +import okhttp3.Cache; | |
11 | + | |
12 | +/** | |
13 | + * Created by Horrarndoo on 2017/9/12. | |
14 | + * <p> | |
15 | + */ | |
16 | +public class HttpCache { | |
17 | + | |
18 | + private static final int HTTP_RESPONSE_DISK_CACHE_MAX_SIZE = 50 * 1024 * 1024; | |
19 | + | |
20 | + public static Cache getCache() { | |
21 | + File file=new File(Environment.getExternalStorageDirectory() + File | |
22 | + .separator + "data/NetCache"); | |
23 | + if (!file.getParentFile().exists())file.getParentFile().mkdirs(); | |
24 | + if (!file.exists())file.mkdirs(); | |
25 | + return new Cache(file, | |
26 | + HTTP_RESPONSE_DISK_CACHE_MAX_SIZE); | |
27 | + } | |
28 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/helper/okhttp/NetInterceptor.java
0 → 100644
... | ... | @@ -0,0 +1,49 @@ |
1 | +package com.share.mvpsdk.helper.okhttp; | |
2 | + | |
3 | + | |
4 | +import com.share.mvpsdk.utils.AppUtils; | |
5 | +import com.share.mvpsdk.utils.NetworkConnectionUtils; | |
6 | + | |
7 | +import java.io.IOException; | |
8 | + | |
9 | +import okhttp3.Interceptor; | |
10 | +import okhttp3.Request; | |
11 | +import okhttp3.Response; | |
12 | + | |
13 | +import static com.share.mvpsdk.utils.HttpUtils.getUserAgent; | |
14 | + | |
15 | + | |
16 | +/** | |
17 | + * Created by Horrarndoo on 2017/9/18. | |
18 | + * <p> | |
19 | + * 有网络时的缓存拦截器 | |
20 | + */ | |
21 | + | |
22 | +public class NetInterceptor implements Interceptor{ | |
23 | + @Override | |
24 | + public Response intercept(Chain chain) throws IOException { | |
25 | + // 有网络时, 缓存1分钟, 最大保存时长为60s | |
26 | + int maxAge = 60; | |
27 | + Request request = chain.request(); | |
28 | + | |
29 | + if (NetworkConnectionUtils.isNetworkConnected(AppUtils.getContext())) { | |
30 | + request = request.newBuilder() | |
31 | + .removeHeader("User-Agent") | |
32 | + .header("User-Agent", getUserAgent()) | |
33 | + // .header("User-Agent", "Mozilla/5.0 (Windows NT 6.1; | |
34 | + // WOW64) AppleWebKit/537.36" + | |
35 | + // " (KHTML, like Gecko) Chrome/50.0.2661.102 | |
36 | + // Safari/537.36") | |
37 | + .build(); | |
38 | + | |
39 | + Response response = chain.proceed(request); | |
40 | + return response.newBuilder() | |
41 | + .removeHeader("Pragma") | |
42 | + .removeHeader("Cache-Control") | |
43 | + .header("Cache-Control", "public, max-age=" + maxAge) | |
44 | + .build(); | |
45 | + } | |
46 | + | |
47 | + return chain.proceed(request); | |
48 | + } | |
49 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/helper/okhttp/NoNetInterceptor.java
0 → 100644
... | ... | @@ -0,0 +1,50 @@ |
1 | +package com.share.mvpsdk.helper.okhttp; | |
2 | + | |
3 | + | |
4 | +import com.share.mvpsdk.utils.AppUtils; | |
5 | +import com.share.mvpsdk.utils.NetworkConnectionUtils; | |
6 | + | |
7 | +import java.io.IOException; | |
8 | + | |
9 | +import okhttp3.CacheControl; | |
10 | +import okhttp3.Interceptor; | |
11 | +import okhttp3.Request; | |
12 | +import okhttp3.Response; | |
13 | + | |
14 | +import static com.share.mvpsdk.utils.HttpUtils.getUserAgent; | |
15 | + | |
16 | +/** | |
17 | + * Created by Horrarndoo on 2017/9/18. | |
18 | + * <p> | |
19 | + * 无网络时的缓存拦截器 | |
20 | + */ | |
21 | + | |
22 | +public class NoNetInterceptor implements Interceptor { | |
23 | + @Override | |
24 | + public Response intercept(Chain chain) throws IOException { | |
25 | + // 无网络时,设置超时为4周 | |
26 | + int maxStale = 60 * 60 * 24 * 28; | |
27 | + Request request = chain.request(); | |
28 | + | |
29 | + if (!NetworkConnectionUtils.isNetworkConnected(AppUtils.getContext())) { | |
30 | + request = request.newBuilder() | |
31 | + .cacheControl(CacheControl.FORCE_CACHE) | |
32 | + .removeHeader("User-Agent") | |
33 | + .header("User-Agent", getUserAgent()) | |
34 | + // .header("User-Agent", "Mozilla/5.0 (Windows NT 6.1; | |
35 | + // WOW64) AppleWebKit/537.36" + | |
36 | + // " (KHTML, like Gecko) Chrome/50.0.2661.102 | |
37 | + // Safari/537.36") | |
38 | + .build(); | |
39 | + | |
40 | + Response response = chain.proceed(request); | |
41 | + return response.newBuilder() | |
42 | + .removeHeader("Pragma") | |
43 | + .removeHeader("Cache-Control") | |
44 | + .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale) | |
45 | + .build(); | |
46 | + } | |
47 | + | |
48 | + return chain.proceed(request); | |
49 | + } | |
50 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/helper/okhttp/TrustManager.java
0 → 100644
... | ... | @@ -0,0 +1,54 @@ |
1 | +package com.share.mvpsdk.helper.okhttp; | |
2 | + | |
3 | +import java.security.cert.CertificateException; | |
4 | +import java.security.cert.X509Certificate; | |
5 | + | |
6 | +import javax.net.ssl.SSLContext; | |
7 | +import javax.net.ssl.SSLSocketFactory; | |
8 | +import javax.net.ssl.X509TrustManager; | |
9 | + | |
10 | +/** | |
11 | + * Created by Horrarndoo on 2017/9/12. | |
12 | + * <p> | |
13 | + */ | |
14 | +public class TrustManager { | |
15 | + | |
16 | + public static SSLSocketFactory getUnsafeOkHttpClient() { | |
17 | + try { | |
18 | + // Create a trust manager that does not validate certificate chains | |
19 | + final X509TrustManager[] trustAllCerts = new X509TrustManager[]{new X509TrustManager() { | |
20 | + @Override | |
21 | + public void checkClientTrusted( | |
22 | + X509Certificate[] chain, | |
23 | + String authType) throws CertificateException { | |
24 | + } | |
25 | + | |
26 | + @Override | |
27 | + public void checkServerTrusted( | |
28 | + X509Certificate[] chain, | |
29 | + String authType) throws CertificateException { | |
30 | + } | |
31 | + | |
32 | + @Override | |
33 | + public X509Certificate[] getAcceptedIssuers() { | |
34 | + return new X509Certificate[0]; | |
35 | + } | |
36 | + }}; | |
37 | + | |
38 | + // Install the all-trusting trust manager | |
39 | + final SSLContext sslContext = SSLContext.getInstance("TLS"); | |
40 | + sslContext.init(null, trustAllCerts, | |
41 | + new java.security.SecureRandom()); | |
42 | + // Create an ssl socket factory with our all-trusting manager | |
43 | + final SSLSocketFactory sslSocketFactory = sslContext | |
44 | + .getSocketFactory(); | |
45 | + | |
46 | + | |
47 | + return sslSocketFactory; | |
48 | + } catch (Exception e) { | |
49 | + throw new RuntimeException(e); | |
50 | + } | |
51 | + | |
52 | + } | |
53 | +} | |
54 | + | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/rxbus/BusData.java
0 → 100644
... | ... | @@ -0,0 +1,34 @@ |
1 | +package com.share.mvpsdk.rxbus; | |
2 | + | |
3 | +/** | |
4 | + * RxBus data | |
5 | + * Created by gorden on 2016/7/8. | |
6 | + */ | |
7 | +public class BusData { | |
8 | + String id; | |
9 | + String status; | |
10 | + | |
11 | + public BusData() { | |
12 | + } | |
13 | + | |
14 | + public BusData(String id, String status) { | |
15 | + this.id = id; | |
16 | + this.status = status; | |
17 | + } | |
18 | + | |
19 | + public String getId() { | |
20 | + return id; | |
21 | + } | |
22 | + | |
23 | + public void setId(String id) { | |
24 | + this.id = id; | |
25 | + } | |
26 | + | |
27 | + public String getStatus() { | |
28 | + return status; | |
29 | + } | |
30 | + | |
31 | + public void setStatus(String status) { | |
32 | + this.status = status; | |
33 | + } | |
34 | +} | |
0 | 35 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,355 @@ |
1 | +package com.share.mvpsdk.rxbus; | |
2 | + | |
3 | +import java.lang.reflect.Method; | |
4 | +import java.util.ArrayList; | |
5 | +import java.util.HashMap; | |
6 | +import java.util.Iterator; | |
7 | +import java.util.List; | |
8 | +import java.util.Map; | |
9 | + | |
10 | +import io.reactivex.BackpressureStrategy; | |
11 | +import io.reactivex.Flowable; | |
12 | +import io.reactivex.Scheduler; | |
13 | +import io.reactivex.android.schedulers.AndroidSchedulers; | |
14 | +import io.reactivex.disposables.Disposable; | |
15 | +import io.reactivex.functions.Consumer; | |
16 | +import io.reactivex.functions.Function; | |
17 | +import io.reactivex.functions.Predicate; | |
18 | +import io.reactivex.schedulers.Schedulers; | |
19 | +import io.reactivex.subjects.PublishSubject; | |
20 | +import io.reactivex.subjects.Subject; | |
21 | + | |
22 | +/** | |
23 | + * RxBus | |
24 | + * Created by gorden on 2016/5/12. | |
25 | + * update 2017/3/1 | |
26 | + */ | |
27 | +@SuppressWarnings("unused") | |
28 | +public class RxBus { | |
29 | + public static final String LOG_BUS = "RXBUS_LOG"; | |
30 | + private static volatile RxBus defaultInstance; | |
31 | + | |
32 | + private Map<Class, List<Disposable>> subscriptionsByEventType = new HashMap<>(); | |
33 | + | |
34 | + private Map<Object, List<Class>> eventTypesBySubscriber = new HashMap<>(); | |
35 | + | |
36 | + private Map<Class, List<SubscriberMethod>> subscriberMethodByEventType = new HashMap<>(); | |
37 | + | |
38 | + private final Subject<Object> bus; | |
39 | + | |
40 | + private RxBus() { | |
41 | + this.bus = PublishSubject.create().toSerialized(); | |
42 | + } | |
43 | + | |
44 | + public static RxBus get() { | |
45 | + RxBus rxBus = defaultInstance; | |
46 | + if (defaultInstance == null) { | |
47 | + synchronized (RxBus.class) { | |
48 | + rxBus = defaultInstance; | |
49 | + if (defaultInstance == null) { | |
50 | + rxBus = new RxBus(); | |
51 | + defaultInstance = rxBus; | |
52 | + } | |
53 | + } | |
54 | + } | |
55 | + return rxBus; | |
56 | + } | |
57 | + | |
58 | + /** | |
59 | + * 根据传递的 eventType 类型返回特定类型(eventType)的 被观察者 | |
60 | + * | |
61 | + * @param eventType 事件类型 | |
62 | + * @return return | |
63 | + */ | |
64 | + private <T> Flowable<T> toObservable(Class<T> eventType) { | |
65 | + return bus.toFlowable(BackpressureStrategy.BUFFER).ofType(eventType); | |
66 | + } | |
67 | + | |
68 | + /** | |
69 | + * 根据传递的code和 eventType 类型返回特定类型(eventType)的 被观察者 | |
70 | + * | |
71 | + * @param code 事件code | |
72 | + * @param eventType 事件类型 | |
73 | + */ | |
74 | + private <T> Flowable<T> toObservable(final int code, final Class<T> eventType) { | |
75 | + return bus.toFlowable(BackpressureStrategy.BUFFER).ofType(Message.class) | |
76 | + .filter(new Predicate<Message>() { | |
77 | + @Override | |
78 | + public boolean test(Message o) throws Exception { | |
79 | + return o.getCode() == code && eventType.isInstance(o.getObject()); | |
80 | + } | |
81 | + }).map(new Function<Message, Object>() { | |
82 | + @Override | |
83 | + public Object apply(Message o) throws Exception { | |
84 | + return o.getObject(); | |
85 | + } | |
86 | + }).cast(eventType); | |
87 | + } | |
88 | + | |
89 | + /** | |
90 | + * 注册 | |
91 | + * | |
92 | + * @param subscriber 订阅者 | |
93 | + */ | |
94 | + public void register(Object subscriber) { | |
95 | + Class<?> subClass = subscriber.getClass(); | |
96 | + Method[] methods = subClass.getDeclaredMethods(); | |
97 | + for (Method method : methods) { | |
98 | + if (method.isAnnotationPresent(Subscribe.class)) { | |
99 | + //获得参数类型 | |
100 | + Class[] parameterType = method.getParameterTypes(); | |
101 | + //参数不为空 且参数个数为1 | |
102 | + if (parameterType != null && parameterType.length == 1) { | |
103 | + | |
104 | + Class eventType = parameterType[0]; | |
105 | + | |
106 | + addEventTypeToMap(subscriber, eventType); | |
107 | + Subscribe sub = method.getAnnotation(Subscribe.class); | |
108 | + int code = sub.code(); | |
109 | + ThreadMode threadMode = sub.threadMode(); | |
110 | + | |
111 | + SubscriberMethod subscriberMethod = new SubscriberMethod(subscriber, method, eventType, code, threadMode); | |
112 | + addSubscriberToMap(eventType, subscriberMethod); | |
113 | + | |
114 | + addSubscriber(subscriberMethod); | |
115 | + } else if (parameterType == null || parameterType.length == 0) { | |
116 | + | |
117 | + Class eventType = BusData.class; | |
118 | + | |
119 | + addEventTypeToMap(subscriber, eventType); | |
120 | + Subscribe sub = method.getAnnotation(Subscribe.class); | |
121 | + int code = sub.code(); | |
122 | + ThreadMode threadMode = sub.threadMode(); | |
123 | + | |
124 | + SubscriberMethod subscriberMethod = new SubscriberMethod(subscriber, method, eventType, code, threadMode); | |
125 | + addSubscriberToMap(eventType, subscriberMethod); | |
126 | + | |
127 | + addSubscriber(subscriberMethod); | |
128 | + | |
129 | + } | |
130 | + } | |
131 | + } | |
132 | + } | |
133 | + | |
134 | + | |
135 | + /** | |
136 | + * 将event的类型以订阅中subscriber为key保存到map里 | |
137 | + * | |
138 | + * @param subscriber 订阅者 | |
139 | + * @param eventType event类型 | |
140 | + */ | |
141 | + private void addEventTypeToMap(Object subscriber, Class eventType) { | |
142 | + List<Class> eventTypes = eventTypesBySubscriber.get(subscriber); | |
143 | + if (eventTypes == null) { | |
144 | + eventTypes = new ArrayList<>(); | |
145 | + eventTypesBySubscriber.put(subscriber, eventTypes); | |
146 | + } | |
147 | + | |
148 | + if (!eventTypes.contains(eventType)) { | |
149 | + eventTypes.add(eventType); | |
150 | + } | |
151 | + } | |
152 | + | |
153 | + /** | |
154 | + * 将注解方法信息以event类型为key保存到map中 | |
155 | + * | |
156 | + * @param eventType event类型 | |
157 | + * @param subscriberMethod 注解方法信息 | |
158 | + */ | |
159 | + private void addSubscriberToMap(Class eventType, SubscriberMethod subscriberMethod) { | |
160 | + List<SubscriberMethod> subscriberMethods = subscriberMethodByEventType.get(eventType); | |
161 | + if (subscriberMethods == null) { | |
162 | + subscriberMethods = new ArrayList<>(); | |
163 | + subscriberMethodByEventType.put(eventType, subscriberMethods); | |
164 | + } | |
165 | + | |
166 | + if (!subscriberMethods.contains(subscriberMethod)) { | |
167 | + subscriberMethods.add(subscriberMethod); | |
168 | + } | |
169 | + } | |
170 | + | |
171 | + /** | |
172 | + * 将订阅事件以event类型为key保存到map,用于取消订阅时用 | |
173 | + * | |
174 | + * @param eventType event类型 | |
175 | + * @param disposable 订阅事件 | |
176 | + */ | |
177 | + private void addSubscriptionToMap(Class eventType, Disposable disposable) { | |
178 | + List<Disposable> disposables = subscriptionsByEventType.get(eventType); | |
179 | + if (disposables == null) { | |
180 | + disposables = new ArrayList<>(); | |
181 | + subscriptionsByEventType.put(eventType, disposables); | |
182 | + } | |
183 | + | |
184 | + if (!disposables.contains(disposable)) { | |
185 | + disposables.add(disposable); | |
186 | + } | |
187 | + } | |
188 | + | |
189 | + /** | |
190 | + * 用RxJava添加订阅者 | |
191 | + * | |
192 | + * @param subscriberMethod d | |
193 | + */ | |
194 | + @SuppressWarnings("unchecked") | |
195 | + private void addSubscriber(final SubscriberMethod subscriberMethod) { | |
196 | + Flowable flowable; | |
197 | + if (subscriberMethod.code == -1) { | |
198 | + flowable = toObservable(subscriberMethod.eventType); | |
199 | + } else { | |
200 | + flowable = toObservable(subscriberMethod.code, subscriberMethod.eventType); | |
201 | + } | |
202 | + Disposable subscription = postToObservable(flowable, subscriberMethod) | |
203 | + .subscribe(new Consumer<Object>() { | |
204 | + @Override | |
205 | + public void accept(Object o) throws Exception { | |
206 | + callEvent(subscriberMethod, o); | |
207 | + } | |
208 | + }); | |
209 | + | |
210 | + addSubscriptionToMap(subscriberMethod.subscriber.getClass(), subscription); | |
211 | + } | |
212 | + | |
213 | + /** | |
214 | + * 用于处理订阅事件在那个线程中执行 | |
215 | + * | |
216 | + * @param observable d | |
217 | + * @param subscriberMethod d | |
218 | + * @return Observable | |
219 | + */ | |
220 | + private Flowable postToObservable(Flowable observable, SubscriberMethod subscriberMethod) { | |
221 | + Scheduler scheduler; | |
222 | + switch (subscriberMethod.threadMode) { | |
223 | + case MAIN: | |
224 | + scheduler = AndroidSchedulers.mainThread(); | |
225 | + break; | |
226 | + | |
227 | + case NEW_THREAD: | |
228 | + scheduler = Schedulers.newThread(); | |
229 | + break; | |
230 | + | |
231 | + case CURRENT_THREAD: | |
232 | + scheduler = Schedulers.trampoline(); | |
233 | + break; | |
234 | + default: | |
235 | + throw new IllegalStateException("Unknown thread mode: " + subscriberMethod.threadMode); | |
236 | + } | |
237 | + return observable.observeOn(scheduler); | |
238 | + } | |
239 | + | |
240 | + /** | |
241 | + * 回调到订阅者的方法中 | |
242 | + * | |
243 | + * @param method code | |
244 | + * @param object obj | |
245 | + */ | |
246 | + private void callEvent(SubscriberMethod method, Object object) { | |
247 | + Class eventClass = object.getClass(); | |
248 | + List<SubscriberMethod> methods = subscriberMethodByEventType.get(eventClass); | |
249 | + if (methods != null && methods.size() > 0) { | |
250 | + for (SubscriberMethod subscriberMethod : methods) { | |
251 | + Subscribe sub = subscriberMethod.method.getAnnotation(Subscribe.class); | |
252 | + int c = sub.code(); | |
253 | + if (c == method.code && method.subscriber.equals(subscriberMethod.subscriber) && method.method.equals(subscriberMethod.method)) { | |
254 | + subscriberMethod.invoke(object); | |
255 | + } | |
256 | + | |
257 | + } | |
258 | + } | |
259 | + } | |
260 | + | |
261 | + /** | |
262 | + * 取消注册 | |
263 | + * | |
264 | + * @param subscriber object | |
265 | + */ | |
266 | + public void unRegister(Object subscriber) { | |
267 | + List<Class> subscribedTypes = eventTypesBySubscriber.get(subscriber); | |
268 | + if (subscribedTypes != null) { | |
269 | + for (Class<?> eventType : subscribedTypes) { | |
270 | + unSubscribeByEventType(subscriber.getClass()); | |
271 | + unSubscribeMethodByEventType(subscriber, eventType); | |
272 | + } | |
273 | + eventTypesBySubscriber.remove(subscriber); | |
274 | + } | |
275 | + } | |
276 | + | |
277 | + /** | |
278 | + * subscriptions unsubscribe | |
279 | + * | |
280 | + * @param eventType eventType | |
281 | + */ | |
282 | + private void unSubscribeByEventType(Class eventType) { | |
283 | + List<Disposable> disposables = subscriptionsByEventType.get(eventType); | |
284 | + if (disposables != null) { | |
285 | + Iterator<Disposable> iterator = disposables.iterator(); | |
286 | + while (iterator.hasNext()) { | |
287 | + Disposable disposable = iterator.next(); | |
288 | + if (disposable != null && !disposable.isDisposed()) { | |
289 | + disposable.dispose(); | |
290 | + iterator.remove(); | |
291 | + } | |
292 | + } | |
293 | + } | |
294 | + } | |
295 | + | |
296 | + /** | |
297 | + * 移除subscriber对应的subscriberMethods | |
298 | + * | |
299 | + * @param subscriber subscriber | |
300 | + * @param eventType eventType | |
301 | + */ | |
302 | + private void unSubscribeMethodByEventType(Object subscriber, Class eventType) { | |
303 | + List<SubscriberMethod> subscriberMethods = subscriberMethodByEventType.get(eventType); | |
304 | + if (subscriberMethods != null) { | |
305 | + Iterator<SubscriberMethod> iterator = subscriberMethods.iterator(); | |
306 | + while (iterator.hasNext()) { | |
307 | + SubscriberMethod subscriberMethod = iterator.next(); | |
308 | + if (subscriberMethod.subscriber.equals(subscriber)) { | |
309 | + iterator.remove(); | |
310 | + } | |
311 | + } | |
312 | + } | |
313 | + } | |
314 | + | |
315 | + public void send(int code, Object o) { | |
316 | + bus.onNext(new Message(code, o)); | |
317 | + } | |
318 | + | |
319 | + public void send(Object o) { | |
320 | + bus.onNext(o); | |
321 | + } | |
322 | + | |
323 | + public void send(int code) { | |
324 | + bus.onNext(new Message(code, new BusData())); | |
325 | + } | |
326 | + | |
327 | + private class Message { | |
328 | + private int code; | |
329 | + private Object object; | |
330 | + | |
331 | + public Message() { | |
332 | + } | |
333 | + | |
334 | + private Message(int code, Object o) { | |
335 | + this.code = code; | |
336 | + this.object = o; | |
337 | + } | |
338 | + | |
339 | + private int getCode() { | |
340 | + return code; | |
341 | + } | |
342 | + | |
343 | + public void setCode(int code) { | |
344 | + this.code = code; | |
345 | + } | |
346 | + | |
347 | + private Object getObject() { | |
348 | + return object; | |
349 | + } | |
350 | + | |
351 | + public void setObject(Object object) { | |
352 | + this.object = object; | |
353 | + } | |
354 | + } | |
355 | +} | |
0 | 356 | \ No newline at end of file | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/rxbus/Subscribe.java
0 → 100644
... | ... | @@ -0,0 +1,21 @@ |
1 | +package com.share.mvpsdk.rxbus; | |
2 | + | |
3 | +import java.lang.annotation.Documented; | |
4 | +import java.lang.annotation.ElementType; | |
5 | +import java.lang.annotation.Retention; | |
6 | +import java.lang.annotation.RetentionPolicy; | |
7 | +import java.lang.annotation.Target; | |
8 | + | |
9 | + | |
10 | +/** | |
11 | + * Rxbus | |
12 | + * Created by gorden on 2016/7/23. | |
13 | + */ | |
14 | +@Documented | |
15 | +@Target(ElementType.METHOD) | |
16 | +@Retention(RetentionPolicy.RUNTIME) | |
17 | +public @interface Subscribe { | |
18 | + int code() default -1; | |
19 | + | |
20 | + ThreadMode threadMode() default ThreadMode.CURRENT_THREAD; | |
21 | +} | |
0 | 22 | \ No newline at end of file | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/rxbus/SubscriberMethod.java
0 → 100644
... | ... | @@ -0,0 +1,44 @@ |
1 | +package com.share.mvpsdk.rxbus; | |
2 | + | |
3 | +import java.lang.reflect.InvocationTargetException; | |
4 | +import java.lang.reflect.Method; | |
5 | + | |
6 | +/** | |
7 | + * | |
8 | + * Created by gorden on 2016/7/23. | |
9 | + */ | |
10 | +public class SubscriberMethod { | |
11 | + public Method method; | |
12 | + public ThreadMode threadMode; | |
13 | + public Class<?> eventType; | |
14 | + public Object subscriber; | |
15 | + public int code; | |
16 | + | |
17 | + public SubscriberMethod(Object subscriber, Method method, Class<?> eventType, int code,ThreadMode threadMode) { | |
18 | + this.method = method; | |
19 | + this.threadMode = threadMode; | |
20 | + this.eventType = eventType; | |
21 | + this.subscriber = subscriber; | |
22 | + this.code = code; | |
23 | + } | |
24 | + | |
25 | + | |
26 | + /** | |
27 | + * 调用方法 | |
28 | + * @param o 参数 | |
29 | + */ | |
30 | + public void invoke(Object o){ | |
31 | + try { | |
32 | + Class[] parameterType = method.getParameterTypes(); | |
33 | + if(parameterType != null && parameterType.length == 1){ | |
34 | + method.invoke(subscriber, o); | |
35 | + }else if(parameterType == null || parameterType.length == 0){ | |
36 | + method.invoke(subscriber); | |
37 | + } | |
38 | + } catch (IllegalAccessException e) { | |
39 | + e.printStackTrace(); | |
40 | + } catch (InvocationTargetException e) { | |
41 | + e.printStackTrace(); | |
42 | + } | |
43 | + } | |
44 | +} | |
0 | 45 | \ No newline at end of file | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/rxbus/ThreadMode.java
0 → 100644
... | ... | @@ -0,0 +1,23 @@ |
1 | +package com.share.mvpsdk.rxbus; | |
2 | + | |
3 | +/** | |
4 | + * | |
5 | + * Created by gorden on 2016/7/23. | |
6 | + */ | |
7 | +public enum ThreadMode { | |
8 | + /** | |
9 | + * current thread | |
10 | + */ | |
11 | + CURRENT_THREAD, | |
12 | + | |
13 | + /** | |
14 | + * android main thread | |
15 | + */ | |
16 | + MAIN, | |
17 | + | |
18 | + | |
19 | + /** | |
20 | + * new thread | |
21 | + */ | |
22 | + NEW_THREAD | |
23 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/AppUtils.java
0 → 100644
... | ... | @@ -0,0 +1,185 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.annotation.SuppressLint; | |
4 | +import android.content.ClipData; | |
5 | +import android.content.ClipboardManager; | |
6 | +import android.content.Context; | |
7 | +import android.content.Intent; | |
8 | +import android.content.pm.PackageInfo; | |
9 | +import android.content.pm.PackageManager; | |
10 | +import android.net.Uri; | |
11 | +import android.os.Environment; | |
12 | +import android.os.Handler; | |
13 | +import android.telephony.TelephonyManager; | |
14 | +import android.util.Log; | |
15 | +import android.view.inputmethod.InputMethodManager; | |
16 | +import android.widget.EditText; | |
17 | + | |
18 | + | |
19 | +import com.share.mvpsdk.global.GlobalApplication; | |
20 | + | |
21 | +import java.io.File; | |
22 | + | |
23 | +import timber.log.Timber; | |
24 | + | |
25 | +/** | |
26 | + * Created by Horrarndoo on 2017/8/31. | |
27 | + * <p> | |
28 | + * App工具类 | |
29 | + */ | |
30 | +public class AppUtils { | |
31 | + | |
32 | + /** | |
33 | + * 获取上下文对象 | |
34 | + * | |
35 | + * @return 上下文对象 | |
36 | + */ | |
37 | + public static Context getContext() { | |
38 | + return GlobalApplication.getContext(); | |
39 | + } | |
40 | + | |
41 | + /** | |
42 | + * 获取全局handler | |
43 | + * | |
44 | + * @return 全局handler | |
45 | + */ | |
46 | + public static Handler getHandler() { | |
47 | + return GlobalApplication.getHandler(); | |
48 | + } | |
49 | + | |
50 | + /** | |
51 | + * 获取主线程id | |
52 | + * | |
53 | + * @return 主线程id | |
54 | + */ | |
55 | + public static int getMainThreadId() { | |
56 | + return GlobalApplication.getMainThreadId(); | |
57 | + } | |
58 | + | |
59 | + /** | |
60 | + * 获取版本名称 | |
61 | + */ | |
62 | + public static String getAppVersionName(Context context) { | |
63 | + String versionName = ""; | |
64 | + try { | |
65 | + // ---get the package info--- | |
66 | + PackageManager pm = context.getPackageManager(); | |
67 | + PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0); | |
68 | + versionName = pi.versionName; | |
69 | + if (versionName == null || versionName.length() <= 0) { | |
70 | + return ""; | |
71 | + } | |
72 | + } catch (Exception e) { | |
73 | + Log.e("VersionInfo", "Exception", e); | |
74 | + } | |
75 | + return versionName; | |
76 | + } | |
77 | + | |
78 | + /** | |
79 | + * 获取版本号 | |
80 | + */ | |
81 | + public static int getAppVersionCode(Context context) { | |
82 | + int versioncode = -1; | |
83 | + try { | |
84 | + // ---get the package info--- | |
85 | + PackageManager pm = context.getPackageManager(); | |
86 | + PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0); | |
87 | + versioncode = pi.versionCode; | |
88 | + } catch (Exception e) { | |
89 | + Log.e("VersionInfo", "Exception", e); | |
90 | + } | |
91 | + return versioncode; | |
92 | + } | |
93 | + | |
94 | + @SuppressLint("MissingPermission") | |
95 | + public static String getIMEI(Context context) { | |
96 | + TelephonyManager tm = (TelephonyManager) context.getSystemService(Context | |
97 | + .TELEPHONY_SERVICE); | |
98 | + return tm.getDeviceId(); | |
99 | + } | |
100 | + | |
101 | + /** | |
102 | + * 显示软键盘 | |
103 | + */ | |
104 | + public static void openSoftInput(EditText et) { | |
105 | + InputMethodManager inputMethodManager = (InputMethodManager) et.getContext() | |
106 | + .getSystemService(Context.INPUT_METHOD_SERVICE); | |
107 | + inputMethodManager.showSoftInput(et, InputMethodManager.HIDE_NOT_ALWAYS); | |
108 | + } | |
109 | + | |
110 | + /** | |
111 | + * 隐藏软键盘 | |
112 | + */ | |
113 | + public static void hideSoftInput(EditText et) { | |
114 | + InputMethodManager inputMethodManager = (InputMethodManager) et.getContext() | |
115 | + .getSystemService(Context.INPUT_METHOD_SERVICE); | |
116 | + inputMethodManager.hideSoftInputFromWindow(et.getWindowToken(), InputMethodManager | |
117 | + .HIDE_NOT_ALWAYS); | |
118 | + } | |
119 | + | |
120 | + /** | |
121 | + * 获取SD卡路径 | |
122 | + * | |
123 | + * @return 如果sd卡不存在则返回null | |
124 | + */ | |
125 | + public static File getSDPath() { | |
126 | + File sdDir = null; | |
127 | + boolean sdCardExist = Environment.getExternalStorageState().equals(Environment | |
128 | + .MEDIA_MOUNTED); //判断sd卡是否存在 | |
129 | + if (sdCardExist) { | |
130 | + sdDir = Environment.getExternalStorageDirectory();//获取跟目录 | |
131 | + } | |
132 | + return sdDir; | |
133 | + } | |
134 | + | |
135 | + /** | |
136 | + * 安装文件 | |
137 | + * | |
138 | + * @param data | |
139 | + */ | |
140 | + public static void promptInstall(Context context, Uri data) { | |
141 | + Intent promptInstall = new Intent(Intent.ACTION_VIEW) | |
142 | + .setDataAndType(data, "application/vnd.android.package-archive"); | |
143 | + // FLAG_ACTIVITY_NEW_TASK 可以保证安装成功时可以正常打开 app | |
144 | + promptInstall.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | |
145 | + context.startActivity(promptInstall); | |
146 | + } | |
147 | + | |
148 | + public static void copy2clipboard(Context context, String text) { | |
149 | + ClipboardManager cm = (ClipboardManager) context.getSystemService(Context | |
150 | + .CLIPBOARD_SERVICE); | |
151 | + ClipData clip = ClipData.newPlainText("clip", text); | |
152 | + cm.setPrimaryClip(clip); | |
153 | + } | |
154 | + | |
155 | + /** | |
156 | + * 判断是否运行在主线程 | |
157 | + * | |
158 | + * @return true:当前线程运行在主线程 | |
159 | + * fasle:当前线程没有运行在主线程 | |
160 | + */ | |
161 | + public static boolean isRunOnUIThread() { | |
162 | + // 获取当前线程id, 如果当前线程id和主线程id相同, 那么当前就是主线程 | |
163 | + int myTid = android.os.Process.myTid(); | |
164 | + if (myTid == getMainThreadId()) { | |
165 | + return true; | |
166 | + } | |
167 | + return false; | |
168 | + } | |
169 | + | |
170 | + /** | |
171 | + * 运行在主线程 | |
172 | + * | |
173 | + * @param r 运行的Runnable对象 | |
174 | + */ | |
175 | + public static void runOnUIThread(Runnable r) { | |
176 | + if (isRunOnUIThread()) { | |
177 | + // 已经是主线程, 直接运行 | |
178 | + r.run(); | |
179 | + } else { | |
180 | + // 如果是子线程, 借助handler让其运行在主线程 | |
181 | + Log.d("66666","getHander="+getHandler()+"r="+r); | |
182 | + getHandler().post(r); | |
183 | + } | |
184 | + } | |
185 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/CacheUtils.java
0 → 100644
... | ... | @@ -0,0 +1,168 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.content.Context; | |
4 | +import android.os.Environment; | |
5 | + | |
6 | +import java.io.File; | |
7 | +import java.math.BigDecimal; | |
8 | + | |
9 | +/** | |
10 | + * Created by ToaHanDong on 2018/3/15. | |
11 | + */ | |
12 | + | |
13 | +public class CacheUtils { | |
14 | + | |
15 | + /** * 清除本应用内部缓存(/data/data/com.xxx.xxx/cache) * * @param context */ | |
16 | + public static void cleanInternalCache(Context context) { | |
17 | + deleteFilesByDirectory(context.getCacheDir()); | |
18 | + } | |
19 | + | |
20 | + /** * 清除本应用所有数据库(/data/data/com.xxx.xxx/databases) * * @param context */ | |
21 | + public static void cleanDatabases(Context context) { | |
22 | + deleteFilesByDirectory(new File("/data/data/" | |
23 | + + context.getPackageName() + "/databases")); | |
24 | + } | |
25 | + | |
26 | + /** | |
27 | + * * 清除本应用SharedPreference(/data/data/com.xxx.xxx/shared_prefs) * * @param | |
28 | + * context | |
29 | + */ | |
30 | + public static void cleanSharedPreference(Context context) { | |
31 | + deleteFilesByDirectory(new File("/data/data/"+ context.getPackageName() + "/shared_prefs")); | |
32 | + } | |
33 | + | |
34 | + /** * 按名字清除本应用数据库 * * @param context * @param dbName */ | |
35 | + public static void cleanDatabaseByName(Context context, String dbName) { | |
36 | + context.deleteDatabase(dbName); | |
37 | + } | |
38 | + | |
39 | + /** * 清除/data/data/com.xxx.xxx/files下的内容 * * @param context */ | |
40 | + public static void cleanFiles(Context context) { | |
41 | + deleteFilesByDirectory(context.getFilesDir()); | |
42 | + } | |
43 | + | |
44 | + /** | |
45 | + * * 清除外部cache下的内容(/mnt/sdcard/android/data/com.xxx.xxx/cache) * * @param | |
46 | + * context | |
47 | + */ | |
48 | + public static void cleanExternalCache(Context context) { | |
49 | + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { | |
50 | + deleteFilesByDirectory(context.getExternalCacheDir()); | |
51 | + } | |
52 | + } | |
53 | + | |
54 | + /** * 清除自定义路径下的文件,使用需小心,请不要误删。而且只支持目录下的文件删除 * * @param filePath */ | |
55 | + public static void cleanCustomCache(String filePath) { | |
56 | + deleteFilesByDirectory1(new File(filePath)); | |
57 | + } | |
58 | + | |
59 | + /** * 清除本应用所有的数据 * * @param context * @param filepath */ | |
60 | + public static void cleanApplicationData(Context context, String filepath) { | |
61 | +// cleanInternalCache(context); | |
62 | +// cleanExternalCache(context); | |
63 | +// cleanDatabases(context); | |
64 | + cleanSharedPreference(context); | |
65 | +// cleanFiles(context); | |
66 | +// cleanCustomCache(filepath); | |
67 | + } | |
68 | + | |
69 | + /** * 删除方法 这里只会删除某个文件夹下的文件,如果传入的directory是个文件,将不做处理 * * @param directory */ | |
70 | + public static void deleteFilesByDirectory(File directory) { | |
71 | + if (directory != null && directory.exists() && directory.isDirectory()) { | |
72 | + for (File item : directory.listFiles()) { | |
73 | + item.delete(); | |
74 | + } | |
75 | + } | |
76 | + } | |
77 | + private static void deleteFilesByDirectory1(File dir){ | |
78 | + if (dir!=null && dir.isDirectory()) { | |
79 | + String[] children = dir.list(); | |
80 | + //递归删除目录中的子目录下 | |
81 | + for (int i = 0; i < children.length; i++) { | |
82 | + StorageUtils.DeleteDirAndFile(new File(dir, children[i])); | |
83 | + } | |
84 | + } | |
85 | + } | |
86 | + | |
87 | + /** | |
88 | + * 清理缓存 | |
89 | + * @param context | |
90 | + * @param filepath | |
91 | + */ | |
92 | + public static void cleanEboardCache(Context context, String filepath) { | |
93 | + cleanInternalCache(context); | |
94 | + cleanExternalCache(context); | |
95 | + cleanFiles(context); | |
96 | + cleanCustomCache(filepath); | |
97 | + } | |
98 | + | |
99 | + public static void clearCache(Context context)throws Exception{ | |
100 | + File file=new File("/data/data/"+ context.getPackageName()); | |
101 | + cleanCustomCache(file.toString()); | |
102 | + } | |
103 | + | |
104 | + public static String getCacheSize(Context context) throws Exception { | |
105 | + File file=new File("/data/data/"+ context.getPackageName()); | |
106 | + return getFormatSize(getFolderSize(file)); | |
107 | + } | |
108 | + | |
109 | + // 获取文件 | |
110 | + //Context.getExternalFilesDir() --> SDCard/Android/data/你的应用的包名/files/ 目录,一般放一些长时间保存的数据 | |
111 | + //Context.getExternalCacheDir() --> SDCard/Android/data/你的应用包名/cache/目录,一般存放临时缓存数据 | |
112 | + public static long getFolderSize(File file) throws Exception { | |
113 | + long size = 0; | |
114 | + try { | |
115 | + File[] fileList = file.listFiles(); | |
116 | + for (int i = 0; i < fileList.length; i++) { | |
117 | + // 如果下面还有文件 | |
118 | + if (fileList[i].isDirectory()) { | |
119 | + size = size + getFolderSize(fileList[i]); | |
120 | + } else { | |
121 | + size = size + fileList[i].length(); | |
122 | + } | |
123 | + } | |
124 | + } catch (Exception e) { | |
125 | + e.printStackTrace(); | |
126 | + } | |
127 | + return size; | |
128 | + } | |
129 | + | |
130 | + | |
131 | + /** | |
132 | + * 格式化单位 | |
133 | + * | |
134 | + * @param size | |
135 | + * @return | |
136 | + */ | |
137 | + public static String getFormatSize(double size) { | |
138 | + double kiloByte = size / 1024; | |
139 | + if (kiloByte < 1) { | |
140 | + return size + "Byte"; | |
141 | + } | |
142 | + | |
143 | + double megaByte = kiloByte / 1024; | |
144 | + if (megaByte < 1) { | |
145 | + BigDecimal result1 = new BigDecimal(Double.toString(kiloByte)); | |
146 | + return result1.setScale(2, BigDecimal.ROUND_HALF_UP) | |
147 | + .toPlainString() + "KB"; | |
148 | + } | |
149 | + | |
150 | + double gigaByte = megaByte / 1024; | |
151 | + if (gigaByte < 1) { | |
152 | + BigDecimal result2 = new BigDecimal(Double.toString(megaByte)); | |
153 | + return result2.setScale(2, BigDecimal.ROUND_HALF_UP) | |
154 | + .toPlainString() + "MB"; | |
155 | + } | |
156 | + | |
157 | + double teraBytes = gigaByte / 1024; | |
158 | + if (teraBytes < 1) { | |
159 | + BigDecimal result3 = new BigDecimal(Double.toString(gigaByte)); | |
160 | + return result3.setScale(2, BigDecimal.ROUND_HALF_UP) | |
161 | + .toPlainString() + "GB"; | |
162 | + } | |
163 | + BigDecimal result4 = new BigDecimal(teraBytes); | |
164 | + return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() | |
165 | + + "TB"; | |
166 | + } | |
167 | + | |
168 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/DBUtils.java
0 → 100644
... | ... | @@ -0,0 +1,114 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.content.ContentValues; | |
4 | +import android.content.Context; | |
5 | +import android.content.SharedPreferences; | |
6 | +import android.database.Cursor; | |
7 | +import android.database.sqlite.SQLiteDatabase; | |
8 | +import android.database.sqlite.SQLiteOpenHelper; | |
9 | + | |
10 | +import com.share.mvpsdk.config.DBConfig; | |
11 | + | |
12 | + | |
13 | +/** | |
14 | + * Created by Horrarndoo on 2017/8/31. | |
15 | + * <p> | |
16 | + * 数据库工具类 | |
17 | + */ | |
18 | +public class DBUtils { | |
19 | + public static final String CREATE_TABLE_IF_NOT_EXISTS = "create table if not exists %s " + | |
20 | + "(id integer primary key autoincrement,title text unique,image text)"; | |
21 | + | |
22 | + | |
23 | + private static DBUtils sDBUtis; | |
24 | + private SQLiteDatabase mSQLiteDatabase; | |
25 | + | |
26 | + private DBUtils(Context context) { | |
27 | + mSQLiteDatabase = new DBHelper(context, DBConfig.DB_NAME + ".db") | |
28 | + .getWritableDatabase(); | |
29 | + } | |
30 | + | |
31 | + public static synchronized DBUtils getDB(Context context) { | |
32 | + if (sDBUtis == null) { | |
33 | + synchronized (DBUtils.class) { | |
34 | + if (sDBUtis == null) | |
35 | + sDBUtis = new DBUtils(context); | |
36 | + } | |
37 | + } | |
38 | + return sDBUtis; | |
39 | + } | |
40 | + | |
41 | + /** | |
42 | + * 插入一个item已读状态到数据表 | |
43 | + * | |
44 | + * @param table 数据表名 | |
45 | + * @param key key值 | |
46 | + * @param value 数据值 | |
47 | + * @return 插入结果 | |
48 | + */ | |
49 | + public boolean insertRead(final String table, String key, int value) { | |
50 | + Cursor cursor = mSQLiteDatabase.query(table, null, null, null, null, null, "id asc"); | |
51 | + //最多缓存200条 | |
52 | + if (cursor.getCount() > 200 && cursor.moveToNext()) { | |
53 | + mSQLiteDatabase.delete(table, "id=?", new String[]{String.valueOf(cursor.getInt | |
54 | + (cursor.getColumnIndex("id")))}); | |
55 | + } | |
56 | + cursor.close(); | |
57 | + final ContentValues contentValues = new ContentValues(); | |
58 | + contentValues.put("key", key); | |
59 | + contentValues.put("is_read", value); | |
60 | + return (mSQLiteDatabase.insertWithOnConflict(table, null, contentValues, SQLiteDatabase | |
61 | + .CONFLICT_REPLACE) > 0); | |
62 | + } | |
63 | + | |
64 | + /** | |
65 | + * 判断item是否已经阅读过 | |
66 | + * | |
67 | + * @param table 数据表名 | |
68 | + * @param key key值 | |
69 | + * @param value | |
70 | + * @return | |
71 | + */ | |
72 | + public boolean isRead(String table, String key, int value) { | |
73 | + boolean isRead = false; | |
74 | + Cursor cursor = mSQLiteDatabase.query(table, null, "key=?", new String[]{key}, null, | |
75 | + null, null); | |
76 | + if (cursor.moveToNext() && (cursor.getInt(cursor.getColumnIndex("is_read")) == value)) { | |
77 | + isRead = true; | |
78 | + } | |
79 | + cursor.close(); | |
80 | + return isRead; | |
81 | + } | |
82 | + | |
83 | + public void insert(String table,String key,String value){ | |
84 | + | |
85 | + } | |
86 | + | |
87 | + public class DBHelper extends SQLiteOpenHelper { | |
88 | + | |
89 | + public DBHelper(Context context, String name) { | |
90 | + super(context, name, null, 1); | |
91 | + } | |
92 | + | |
93 | + @Override | |
94 | + public void onCreate(SQLiteDatabase db) { | |
95 | + //onCreate()方法只有数据库第一次被创建时才会调用,若数据库已存在,此方法不会被调用 | |
96 | + } | |
97 | + | |
98 | + @Override | |
99 | + public void onOpen(SQLiteDatabase db) { | |
100 | + super.onOpen(db); | |
101 | + //数据库打开时就会被调用,将插入新表的操作方到onOpen中 | |
102 | + db.execSQL(String.format(CREATE_TABLE_IF_NOT_EXISTS, DBConfig.TABLE_ZHIHU)); | |
103 | + db.execSQL(String.format(CREATE_TABLE_IF_NOT_EXISTS, DBConfig.TABLE_WANGYI)); | |
104 | + db.execSQL(String.format(CREATE_TABLE_IF_NOT_EXISTS, DBConfig.TABLE_WEIXIN)); | |
105 | + db.execSQL(String.format(CREATE_TABLE_IF_NOT_EXISTS, DBConfig.TABLE_GANKIO_DAY)); | |
106 | + db.execSQL(String.format(CREATE_TABLE_IF_NOT_EXISTS, DBConfig.TABLE_GANKIO_CUSTOM)); | |
107 | + } | |
108 | + | |
109 | + @Override | |
110 | + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { | |
111 | + //只有数据库进行版本升级时被调用 | |
112 | + } | |
113 | + } | |
114 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/DateUtils.java
0 → 100644
... | ... | @@ -0,0 +1,259 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.text.TextUtils; | |
4 | +import android.text.format.DateFormat; | |
5 | + | |
6 | +import java.text.ParseException; | |
7 | +import java.text.SimpleDateFormat; | |
8 | +import java.util.Calendar; | |
9 | +import java.util.Date; | |
10 | +import java.util.Locale; | |
11 | + | |
12 | +/** | |
13 | + * Created by Horrarndoo on 2017/8/31. | |
14 | + * <p> | |
15 | + * 日期时间工具类 | |
16 | + */ | |
17 | +public class DateUtils { | |
18 | + | |
19 | + public static final long ONE_SECOND_MILLIONS = 1000; | |
20 | + public static final long ONE_MINUTE_MILLIONS = 60 * ONE_SECOND_MILLIONS; | |
21 | + public static final long ONE_HOUR_MILLIONS = 60 * ONE_MINUTE_MILLIONS; | |
22 | + public static final long ONE_DAY_MILLIONS = 24 * ONE_HOUR_MILLIONS; | |
23 | + public static final int DAY_OF_YEAR = 365; | |
24 | + | |
25 | + // 日期格式为 2016-02-03 17:04:58 | |
26 | + public static final String PATTERN_DATE = "yyyy年MM月dd日"; | |
27 | + public static final String PATTERN_TIME = "HH:mm:ss"; | |
28 | + public static final String PATTERN_SPLIT = " "; | |
29 | + public static final String PATTERN = PATTERN_DATE + PATTERN_SPLIT + PATTERN_TIME; | |
30 | + | |
31 | + public static String getShortTime(String dateStr) { | |
32 | + String str; | |
33 | + | |
34 | + Date date = str2date(dateStr); | |
35 | + Date curDate = new Date(); | |
36 | + | |
37 | + long durTime = curDate.getTime() - date.getTime(); | |
38 | + int dayDiff = calculateDayDiff(date, curDate); | |
39 | + | |
40 | + if (durTime <= 10 * ONE_MINUTE_MILLIONS) { | |
41 | + str = "刚刚"; | |
42 | + } else if (durTime < ONE_HOUR_MILLIONS) { | |
43 | + str = durTime / ONE_MINUTE_MILLIONS + "分钟前"; | |
44 | + } else if (dayDiff == 0) { | |
45 | + str = durTime / ONE_HOUR_MILLIONS + "小时前"; | |
46 | + } else if (dayDiff == -1) { | |
47 | + str = "昨天" + DateFormat.format("HH:mm", date); | |
48 | + } else if (isSameYear(date, curDate) && dayDiff < -1) { | |
49 | + str = DateFormat.format("MM-dd", date).toString(); | |
50 | + } else { | |
51 | + str = DateFormat.format("yyyy-MM", date).toString(); | |
52 | + } | |
53 | + | |
54 | + return str; | |
55 | + } | |
56 | + | |
57 | + public static String format(long millis){ | |
58 | + SimpleDateFormat format = new SimpleDateFormat("MM/dd", Locale.getDefault()); | |
59 | + return format.format(millis); | |
60 | + } | |
61 | + | |
62 | + /** | |
63 | + * 获取日期 PATTERN_DATE 部分 | |
64 | + */ | |
65 | + public static String getDate(String date) { | |
66 | + if (TextUtils.isEmpty(date) || !date.contains(PATTERN_SPLIT)) { | |
67 | + return ""; | |
68 | + } | |
69 | + return date.split(PATTERN_SPLIT)[0]; | |
70 | + } | |
71 | + | |
72 | + public static String dateFormat(Date date,String fomart){ | |
73 | + SimpleDateFormat simpleDateFormat=new SimpleDateFormat(fomart); | |
74 | + return simpleDateFormat.format(date); | |
75 | + } | |
76 | + | |
77 | + /** | |
78 | + * 原有日期上累加月 | |
79 | + * | |
80 | + * @return 累加后的日期 PATTERN_DATE 部分 | |
81 | + */ | |
82 | + public static String addMonth(String date, int moonCount) { | |
83 | + //如果date为空 就用当前时间 | |
84 | + if (TextUtils.isEmpty(date)) { | |
85 | + SimpleDateFormat df = new SimpleDateFormat(PATTERN_DATE + PATTERN_SPLIT + PATTERN_TIME); | |
86 | + date = df.format(new Date()); | |
87 | + } | |
88 | + Calendar calendar = str2calendar(date); | |
89 | + calendar.add(Calendar.MONTH, moonCount); | |
90 | + return getDate(calendar2str(calendar)); | |
91 | + } | |
92 | + | |
93 | + /** | |
94 | + * 计算天数差 | |
95 | + */ | |
96 | + public static int calculateDayDiff(Date targetTime, Date compareTime) { | |
97 | + boolean sameYear = isSameYear(targetTime, compareTime); | |
98 | + if (sameYear) { | |
99 | + return calculateDayDiffOfSameYear(targetTime, compareTime); | |
100 | + } else { | |
101 | + int dayDiff = 0; | |
102 | + | |
103 | + // 累计年数差的整年天数 | |
104 | + int yearDiff = calculateYearDiff(targetTime, compareTime); | |
105 | + dayDiff += yearDiff * DAY_OF_YEAR; | |
106 | + | |
107 | + // 累计同一年内的天数 | |
108 | + dayDiff += calculateDayDiffOfSameYear(targetTime, compareTime); | |
109 | + | |
110 | + return dayDiff; | |
111 | + } | |
112 | + } | |
113 | + | |
114 | + /** | |
115 | + * 计算同一年内的天数差 | |
116 | + */ | |
117 | + public static int calculateDayDiffOfSameYear(Date targetTime, Date compareTime) { | |
118 | + if (targetTime == null || compareTime == null) { | |
119 | + return 0; | |
120 | + } | |
121 | + | |
122 | + Calendar tarCalendar = Calendar.getInstance(); | |
123 | + tarCalendar.setTime(targetTime); | |
124 | + int tarDayOfYear = tarCalendar.get(Calendar.DAY_OF_YEAR); | |
125 | + | |
126 | + Calendar compareCalendar = Calendar.getInstance(); | |
127 | + compareCalendar.setTime(compareTime); | |
128 | + int comDayOfYear = compareCalendar.get(Calendar.DAY_OF_YEAR); | |
129 | + | |
130 | + return tarDayOfYear - comDayOfYear; | |
131 | + } | |
132 | + | |
133 | + /** | |
134 | + * 计算年数差 | |
135 | + */ | |
136 | + public static int calculateYearDiff(Date targetTime, Date compareTime) { | |
137 | + if (targetTime == null || compareTime == null) { | |
138 | + return 0; | |
139 | + } | |
140 | + | |
141 | + Calendar tarCalendar = Calendar.getInstance(); | |
142 | + tarCalendar.setTime(targetTime); | |
143 | + int tarYear = tarCalendar.get(Calendar.YEAR); | |
144 | + | |
145 | + Calendar compareCalendar = Calendar.getInstance(); | |
146 | + compareCalendar.setTime(compareTime); | |
147 | + int comYear = compareCalendar.get(Calendar.YEAR); | |
148 | + | |
149 | + return tarYear - comYear; | |
150 | + } | |
151 | + | |
152 | + /** | |
153 | + * 计算月数差 | |
154 | + * | |
155 | + * @param targetTime | |
156 | + * @param compareTime | |
157 | + * @return | |
158 | + */ | |
159 | + public static int calculateMonthDiff(String targetTime, String compareTime) { | |
160 | + return calculateMonthDiff(str2date(targetTime, PATTERN_DATE), | |
161 | + str2date(compareTime, PATTERN_DATE)); | |
162 | + } | |
163 | + | |
164 | + /** | |
165 | + * 计算月数差 | |
166 | + * | |
167 | + * @param targetTime | |
168 | + * @param compareTime | |
169 | + * @return | |
170 | + */ | |
171 | + public static int calculateMonthDiff(Date targetTime, Date compareTime) { | |
172 | + Calendar tarCalendar = Calendar.getInstance(); | |
173 | + tarCalendar.setTime(targetTime); | |
174 | + int tarYear = tarCalendar.get(Calendar.YEAR); | |
175 | + int tarMonth = tarCalendar.get(Calendar.MONTH); | |
176 | + | |
177 | + Calendar compareCalendar = Calendar.getInstance(); | |
178 | + compareCalendar.setTime(compareTime); | |
179 | + int comYear = compareCalendar.get(Calendar.YEAR); | |
180 | + int comMonth = compareCalendar.get(Calendar.MONTH); | |
181 | + return ((tarYear - comYear) * 12 + tarMonth - comMonth); | |
182 | + | |
183 | + } | |
184 | + | |
185 | + /** | |
186 | + * 是否为同一年 | |
187 | + */ | |
188 | + public static boolean isSameYear(Date targetTime, Date compareTime) { | |
189 | + if (targetTime == null || compareTime == null) { | |
190 | + return false; | |
191 | + } | |
192 | + | |
193 | + Calendar tarCalendar = Calendar.getInstance(); | |
194 | + tarCalendar.setTime(targetTime); | |
195 | + int tarYear = tarCalendar.get(Calendar.YEAR); | |
196 | + | |
197 | + Calendar compareCalendar = Calendar.getInstance(); | |
198 | + compareCalendar.setTime(compareTime); | |
199 | + int comYear = compareCalendar.get(Calendar.YEAR); | |
200 | + | |
201 | + return tarYear == comYear; | |
202 | + } | |
203 | + | |
204 | + public static Date str2date(String str, String format) { | |
205 | + Date date = null; | |
206 | + try { | |
207 | + if (str != null) { | |
208 | + SimpleDateFormat sdf = new SimpleDateFormat(format); | |
209 | + date = sdf.parse(str); | |
210 | + } | |
211 | + } catch (ParseException e) { | |
212 | + e.printStackTrace(); | |
213 | + } | |
214 | + return date; | |
215 | + } | |
216 | + | |
217 | + public static Date str2date(String str) { | |
218 | + return str2date(str, PATTERN); | |
219 | + } | |
220 | + | |
221 | + public static String date2str(Date date) { | |
222 | + return date2str(date, PATTERN); | |
223 | + } | |
224 | + | |
225 | + public static String date2str(Date date, String format) { | |
226 | + SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.CHINA); | |
227 | + return sdf.format(date); | |
228 | + } | |
229 | + | |
230 | + public static Calendar str2calendar(String str) { | |
231 | + Calendar calendar = null; | |
232 | + Date date = str2date(str); | |
233 | + if (date != null) { | |
234 | + calendar = Calendar.getInstance(); | |
235 | + calendar.setTime(date); | |
236 | + } | |
237 | + return calendar; | |
238 | + } | |
239 | + | |
240 | + | |
241 | + public static Calendar str2calendar(String str, String format) { | |
242 | + Calendar calendar = null; | |
243 | + Date date = str2date(str, format); | |
244 | + if (date != null) { | |
245 | + calendar = Calendar.getInstance(); | |
246 | + calendar.setTime(date); | |
247 | + } | |
248 | + return calendar; | |
249 | + } | |
250 | + | |
251 | + public static String calendar2str(Calendar calendar) { | |
252 | + return date2str(calendar.getTime()); | |
253 | + } | |
254 | + | |
255 | + public static String calendar2str(Calendar calendar, String format) { | |
256 | + return date2str(calendar.getTime(), format); | |
257 | + } | |
258 | + | |
259 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/DialogUtils.java
0 → 100644
... | ... | @@ -0,0 +1,60 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.app.Dialog; | |
4 | +import android.app.ProgressDialog; | |
5 | +import android.content.Context; | |
6 | +import android.content.DialogInterface; | |
7 | +import android.support.v7.app.AlertDialog; | |
8 | + | |
9 | +import com.share.mvpsdk.R; | |
10 | + | |
11 | + | |
12 | +/** | |
13 | + * Created by Horrarndoo on 2017/8/31. | |
14 | + * <p> | |
15 | + * 对话框工具类, 提供常用对话框显示, 使用support.v7包内的AlertDialog样式 | |
16 | + */ | |
17 | +public class DialogUtils { | |
18 | + | |
19 | + public static Dialog createProgressDialog(Context context) { | |
20 | + return createProgressDialog(context, true); | |
21 | + } | |
22 | + | |
23 | + public static Dialog createProgressDialog(Context context, boolean needCancle) { | |
24 | + ProgressDialog dialog = new ProgressDialog(context); | |
25 | + dialog.setMessage("Loading ..."); | |
26 | + dialog.setCancelable(needCancle); | |
27 | + dialog.setCanceledOnTouchOutside(false); | |
28 | + return dialog; | |
29 | + } | |
30 | + | |
31 | + public static Dialog showCommonDialog(Context context, String message, | |
32 | + DialogInterface.OnClickListener listener) { | |
33 | + return showCommonDialog(context, message, context.getString(R.string.dialog_positive), | |
34 | + context.getString(R.string.dialog_negative), listener); | |
35 | + } | |
36 | + | |
37 | + public static Dialog showCommonDialog(Context context, String message, String positiveText, | |
38 | + String negativeText, DialogInterface.OnClickListener | |
39 | + listener) { | |
40 | + return new AlertDialog.Builder(context) | |
41 | + .setMessage(message) | |
42 | + .setPositiveButton(positiveText, listener) | |
43 | + .setNegativeButton(negativeText, null) | |
44 | + .show(); | |
45 | + } | |
46 | + | |
47 | + public static Dialog showConfirmDialog(Context context, String message, | |
48 | + DialogInterface.OnClickListener listener) { | |
49 | + return showConfirmDialog(context, message, context.getString(R.string.dialog_positive), | |
50 | + listener); | |
51 | + } | |
52 | + | |
53 | + public static Dialog showConfirmDialog(Context context, String message, String positiveText, | |
54 | + DialogInterface.OnClickListener listener) { | |
55 | + return new AlertDialog.Builder(context) | |
56 | + .setMessage(message) | |
57 | + .setPositiveButton(positiveText, listener) | |
58 | + .show(); | |
59 | + } | |
60 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/DisplayUtils.java
0 → 100644
... | ... | @@ -0,0 +1,195 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | +import android.content.Context; | |
5 | +import android.graphics.Bitmap; | |
6 | +import android.graphics.Canvas; | |
7 | +import android.os.Build; | |
8 | +import android.renderscript.Allocation; | |
9 | +import android.renderscript.Element; | |
10 | +import android.renderscript.RenderScript; | |
11 | +import android.renderscript.ScriptIntrinsicBlur; | |
12 | +import android.util.DisplayMetrics; | |
13 | +import android.view.View; | |
14 | +import android.widget.ImageView; | |
15 | + | |
16 | +import com.bumptech.glide.Glide; | |
17 | +import com.share.mvpsdk.R; | |
18 | + | |
19 | +import java.io.File; | |
20 | + | |
21 | +import jp.wasabeef.glide.transformations.BlurTransformation; | |
22 | + | |
23 | +/** | |
24 | + * Created by Horrarndoo on 2017/8/31. | |
25 | + * <p> | |
26 | + * 显示相关工具类 | |
27 | + */ | |
28 | +public class DisplayUtils { | |
29 | + /** | |
30 | + * 将px值转换为dp值 | |
31 | + */ | |
32 | + public static int px2dp(float pxValue) { | |
33 | + final float scale = AppUtils.getContext().getResources().getDisplayMetrics().density; | |
34 | + return (int) (pxValue / scale + 0.5f); | |
35 | + } | |
36 | + | |
37 | + /** | |
38 | + * 将dp值转换为px值 | |
39 | + */ | |
40 | + public static int dp2px(float dpValue) { | |
41 | + final float scale = AppUtils.getContext().getResources().getDisplayMetrics().density; | |
42 | + return (int) (dpValue * scale + 0.5f); | |
43 | + } | |
44 | + | |
45 | + /** | |
46 | + * 将px值转换为sp值 | |
47 | + */ | |
48 | + public static int px2sp(float pxValue) { | |
49 | + final float scale = AppUtils.getContext().getResources().getDisplayMetrics().scaledDensity; | |
50 | + return (int) (pxValue / scale + 0.5f); | |
51 | + } | |
52 | + | |
53 | + /** | |
54 | + * 将sp值转换为px值 | |
55 | + */ | |
56 | + public static int sp2px(float dpValue) { | |
57 | + final float scale = AppUtils.getContext().getResources().getDisplayMetrics().scaledDensity; | |
58 | + return (int) (dpValue * scale + 0.5f); | |
59 | + } | |
60 | + | |
61 | + /** | |
62 | + * 获取屏幕宽度 | |
63 | + */ | |
64 | + public static int getScreenWidthPixels(Activity context) { | |
65 | + DisplayMetrics metric = new DisplayMetrics(); | |
66 | + context.getWindowManager().getDefaultDisplay().getMetrics(metric); | |
67 | + return metric.widthPixels; | |
68 | + } | |
69 | + | |
70 | + /** | |
71 | + * 获取屏幕高度 | |
72 | + */ | |
73 | + public static int getScreenHeightPixels(Activity context) { | |
74 | + DisplayMetrics metric = new DisplayMetrics(); | |
75 | + context.getWindowManager().getDefaultDisplay().getMetrics(metric); | |
76 | + return metric.heightPixels; | |
77 | + } | |
78 | + | |
79 | + /** | |
80 | + * 将一个view转换成bitmap位图 | |
81 | + * | |
82 | + * @param view 要转换的View | |
83 | + * @return view转换的bitmap | |
84 | + */ | |
85 | + public static Bitmap viewToBitmap(View view) { | |
86 | + Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), | |
87 | + Bitmap.Config.ARGB_8888); | |
88 | + view.draw(new Canvas(bitmap)); | |
89 | + return bitmap; | |
90 | + } | |
91 | + | |
92 | + /** | |
93 | + * 获取模糊虚化的bitmap | |
94 | + * | |
95 | + * @param context | |
96 | + * @param bitmap 要模糊的图片 | |
97 | + * @param radius 模糊等级 >=0 && <=25 | |
98 | + * @return | |
99 | + */ | |
100 | + public static Bitmap getBlurBitmap(Context context, Bitmap bitmap, int radius) { | |
101 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { | |
102 | + return blurBitmap(context, bitmap, radius); | |
103 | + } | |
104 | + return bitmap; | |
105 | + } | |
106 | + | |
107 | + /** | |
108 | + * android系统的模糊方法 | |
109 | + * | |
110 | + * @param bitmap 要模糊的图片 | |
111 | + * @param radius 模糊等级 >=0 && <=25 | |
112 | + */ | |
113 | + public static Bitmap blurBitmap(Context context, Bitmap bitmap, int radius) { | |
114 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { | |
115 | + //Let's create an empty bitmap with the same size of the bitmap we want to blur | |
116 | + Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap | |
117 | + .Config.ARGB_8888); | |
118 | + //Instantiate a new Renderscript | |
119 | + RenderScript rs = RenderScript.create(context); | |
120 | + //Create an Intrinsic Blur Script using the Renderscript | |
121 | + ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); | |
122 | + //Create the Allocations (in/out) with the Renderscript and the in/out bitmaps | |
123 | + Allocation allIn = Allocation.createFromBitmap(rs, bitmap); | |
124 | + Allocation allOut = Allocation.createFromBitmap(rs, outBitmap); | |
125 | + //Set the radius of the blur | |
126 | + blurScript.setRadius(radius); | |
127 | + //Perform the Renderscript | |
128 | + blurScript.setInput(allIn); | |
129 | + blurScript.forEach(allOut); | |
130 | + //Copy the final bitmap created by the out Allocation to the outBitmap | |
131 | + allOut.copyTo(outBitmap); | |
132 | + //recycle the original bitmap | |
133 | + bitmap.recycle(); | |
134 | + //After finishing everything, we destroy the Renderscript. | |
135 | + rs.destroy(); | |
136 | + return outBitmap; | |
137 | + } else { | |
138 | + return bitmap; | |
139 | + } | |
140 | + } | |
141 | + | |
142 | + /** | |
143 | + * 显示网络虚化图片 | |
144 | + * | |
145 | + * @param context context | |
146 | + * @param imgUrl 图片url | |
147 | + * @param imageView 要显示的imageview | |
148 | + */ | |
149 | + public static void displayBlurImg(Context context, final String imgUrl, ImageView imageView) { | |
150 | + // "23":模糊度;"4":图片缩放4倍后再进行模糊 | |
151 | + Glide.with(context) | |
152 | + .load(imgUrl) | |
153 | + .error(R.drawable.stackblur_default) | |
154 | + .placeholder(R.drawable.stackblur_default) | |
155 | + .crossFade(300) | |
156 | + .bitmapTransform(new BlurTransformation(context, 23, 4)) | |
157 | + .into(imageView); | |
158 | + } | |
159 | + | |
160 | + /** | |
161 | + * 显示本地虚化图片 | |
162 | + * | |
163 | + * @param context context | |
164 | + * @param file 本地图片file | |
165 | + * @param imageView 要显示的imageview | |
166 | + */ | |
167 | + public static void displayBlurImg(Context context, File file, ImageView imageView) { | |
168 | + // "23":模糊度;"4":图片缩放4倍后再进行模糊 | |
169 | + Glide.with(context) | |
170 | + .load(file) | |
171 | + .error(R.drawable.stackblur_default) | |
172 | + .placeholder(R.drawable.stackblur_default) | |
173 | + .crossFade(300) | |
174 | + .bitmapTransform(new BlurTransformation(context, 23, 4)) | |
175 | + .into(imageView); | |
176 | + } | |
177 | + | |
178 | + /** | |
179 | + * 显示资源虚化图片 | |
180 | + * | |
181 | + * @param context context | |
182 | + * @param resourceId 图片资源id | |
183 | + * @param imageView 要显示的imageview | |
184 | + */ | |
185 | + public static void displayBlurImg(Context context, Integer resourceId, ImageView imageView) { | |
186 | + // "23":模糊度;"4":图片缩放4倍后再进行模糊 | |
187 | + Glide.with(context) | |
188 | + .load(resourceId) | |
189 | + .error(R.drawable.stackblur_default) | |
190 | + .placeholder(R.drawable.stackblur_default) | |
191 | + .crossFade(300) | |
192 | + .bitmapTransform(new BlurTransformation(context, 23, 4)) | |
193 | + .into(imageView); | |
194 | + } | |
195 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/FileUtils.java
0 → 100644
... | ... | @@ -0,0 +1,291 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.content.ContentResolver; | |
4 | +import android.content.Context; | |
5 | +import android.content.Intent; | |
6 | +import android.database.Cursor; | |
7 | +import android.graphics.Bitmap; | |
8 | +import android.net.Uri; | |
9 | +import android.os.Environment; | |
10 | +import android.provider.MediaStore; | |
11 | +import android.text.TextUtils; | |
12 | + | |
13 | +import java.io.BufferedInputStream; | |
14 | +import java.io.BufferedOutputStream; | |
15 | +import java.io.File; | |
16 | +import java.io.FileInputStream; | |
17 | +import java.io.FileNotFoundException; | |
18 | +import java.io.FileOutputStream; | |
19 | +import java.io.IOException; | |
20 | +import java.io.InputStream; | |
21 | + | |
22 | +/** | |
23 | + * Created by Horrarndoo on 2017/8/31. | |
24 | + * <p> | |
25 | + * 读取文件工具类 | |
26 | + */ | |
27 | +public class FileUtils { | |
28 | + private static final String TAG = "FileUtils"; | |
29 | + | |
30 | + /** | |
31 | + * Convert byte[] to hex string.将byte转换成int, | |
32 | + * 然后利用Integer.toHexString(int)来转换成16进制字符串。 | |
33 | + * | |
34 | + * @param src byte[] data | |
35 | + * @return hex string | |
36 | + */ | |
37 | + public static String bytesToHexString(byte[] src) { | |
38 | + StringBuilder stringBuilder = new StringBuilder(""); | |
39 | + if (src == null || src.length <= 0) { | |
40 | + return null; | |
41 | + } | |
42 | + for (int i = 0; i < src.length; i++) { | |
43 | + int v = src[i] & 0xFF; | |
44 | + String hv = Integer.toHexString(v); | |
45 | + if (hv.length() < 2) { | |
46 | + stringBuilder.append(0); | |
47 | + } | |
48 | + stringBuilder.append(hv); | |
49 | + } | |
50 | + return stringBuilder.toString(); | |
51 | + } | |
52 | + | |
53 | + /** | |
54 | + * 根据文件名称和路径,获取sd卡中的文件,以File形式返回byte | |
55 | + */ | |
56 | + public static File getFile(String fileName, String folder) | |
57 | + throws IOException { | |
58 | + String state = Environment.getExternalStorageState(); | |
59 | + if (state.equals(Environment.MEDIA_MOUNTED)) { | |
60 | + File pathFile = new File(Environment.getExternalStorageDirectory() | |
61 | + + folder); | |
62 | + // && !pathFile .isDirectory() | |
63 | + if (!pathFile.exists()) { | |
64 | + pathFile.mkdirs(); | |
65 | + } | |
66 | + File file = new File(pathFile, fileName); | |
67 | + return file; | |
68 | + } | |
69 | + return null; | |
70 | + } | |
71 | + | |
72 | + /** | |
73 | + * 根据文件名称和路径,获取sd卡中的文件,判断文件是否存在,存在返回true | |
74 | + */ | |
75 | + public static Boolean checkFile(String fileName, String folder) | |
76 | + throws IOException { | |
77 | + | |
78 | + File targetFile = getFile(fileName, folder); | |
79 | + | |
80 | + if (!targetFile.exists()) { | |
81 | + return false; | |
82 | + } else { | |
83 | + return true; | |
84 | + } | |
85 | + } | |
86 | + | |
87 | + /** | |
88 | + * 根据Uri返回文件绝对路径 | |
89 | + * 兼容了file:///开头的 和 content://开头的情况 | |
90 | + */ | |
91 | + public static String getRealFilePathFromUri(final Context context, final Uri uri) { | |
92 | + if (null == uri) | |
93 | + return null; | |
94 | + final String scheme = uri.getScheme(); | |
95 | + String data = null; | |
96 | + if (scheme == null) { | |
97 | + data = uri.getPath(); | |
98 | + } else if (ContentResolver.SCHEME_FILE.equalsIgnoreCase(scheme)) { | |
99 | + data = uri.getPath(); | |
100 | + } else if (ContentResolver.SCHEME_CONTENT.equalsIgnoreCase(scheme)) { | |
101 | + Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore | |
102 | + .Images.ImageColumns.DATA}, null, null, null); | |
103 | + if (null != cursor) { | |
104 | + if (cursor.moveToFirst()) { | |
105 | + int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); | |
106 | + if (index > -1) { | |
107 | + data = cursor.getString(index); | |
108 | + } | |
109 | + } | |
110 | + cursor.close(); | |
111 | + } | |
112 | + } | |
113 | + return data; | |
114 | + } | |
115 | + | |
116 | + /** | |
117 | + * 检查文件是否存在 | |
118 | + */ | |
119 | + public static String checkDirPath(String dirPath) { | |
120 | + if (TextUtils.isEmpty(dirPath)) { | |
121 | + return ""; | |
122 | + } | |
123 | + File dir = new File(dirPath); | |
124 | + if (!dir.exists()) { | |
125 | + dir.mkdirs(); | |
126 | + } | |
127 | + return dirPath; | |
128 | + } | |
129 | + | |
130 | + public static void copyFile(File sourcefile, File targetFile) { | |
131 | + FileInputStream input = null; | |
132 | + BufferedInputStream inbuff = null; | |
133 | + FileOutputStream out = null; | |
134 | + BufferedOutputStream outbuff = null; | |
135 | + | |
136 | + try { | |
137 | + | |
138 | + input = new FileInputStream(sourcefile); | |
139 | + inbuff = new BufferedInputStream(input); | |
140 | + | |
141 | + out = new FileOutputStream(targetFile); | |
142 | + outbuff = new BufferedOutputStream(out); | |
143 | + | |
144 | + byte[] b = new byte[1024 * 5]; | |
145 | + int len = 0; | |
146 | + while ((len = inbuff.read(b)) != -1) { | |
147 | + outbuff.write(b, 0, len); | |
148 | + } | |
149 | + outbuff.flush(); | |
150 | + } catch (Exception ex) { | |
151 | + } finally { | |
152 | + try { | |
153 | + if (inbuff != null) | |
154 | + inbuff.close(); | |
155 | + if (outbuff != null) | |
156 | + outbuff.close(); | |
157 | + if (out != null) | |
158 | + out.close(); | |
159 | + if (input != null) | |
160 | + input.close(); | |
161 | + } catch (Exception ex) { | |
162 | + | |
163 | + } | |
164 | + } | |
165 | + } | |
166 | + | |
167 | + /** | |
168 | + * 保存图片到本机 | |
169 | + * | |
170 | + * @param context context | |
171 | + * @param fileName 文件名 | |
172 | + * @param file file | |
173 | + * @param saveResultCallback 保存结果callback | |
174 | + */ | |
175 | + public static void saveImage(final Context context, final String fileName, final File file, | |
176 | + final SaveResultCallback saveResultCallback) { | |
177 | + new Thread(new Runnable() { | |
178 | + @Override | |
179 | + public void run() { | |
180 | + File appDir = new File(Environment.getExternalStorageDirectory(), "yizhi"); | |
181 | + if (!appDir.exists()) { | |
182 | + appDir.mkdir(); | |
183 | + } | |
184 | + String saveFileName = "yizhi_pic"; | |
185 | + if (fileName.contains(".png") || fileName.contains(".gif")) { | |
186 | + String fileFormat = fileName.substring(fileName.lastIndexOf(".")); | |
187 | + saveFileName = MD5Utils.getMD5("yizhi_pic" + fileName) + fileFormat; | |
188 | + } else { | |
189 | + saveFileName = MD5Utils.getMD5("yizhi_pic" + fileName) + ".png"; | |
190 | + } | |
191 | + saveFileName = saveFileName.substring(20);//取前20位作为SaveName | |
192 | + File savefile = new File(appDir, saveFileName); | |
193 | + try { | |
194 | + InputStream is = new FileInputStream(file); | |
195 | + FileOutputStream fos = new FileOutputStream(savefile); | |
196 | + byte[] buffer = new byte[1024 * 1024];//1M缓冲区 | |
197 | + int count = 0; | |
198 | + while ((count = is.read(buffer)) > 0) { | |
199 | + fos.write(buffer, 0, count); | |
200 | + } | |
201 | + fos.close(); | |
202 | + is.close(); | |
203 | + saveResultCallback.onSavedSuccess(); | |
204 | + } catch (FileNotFoundException e) { | |
205 | + saveResultCallback.onSavedFailed(); | |
206 | + e.printStackTrace(); | |
207 | + } catch (IOException e) { | |
208 | + saveResultCallback.onSavedFailed(); | |
209 | + e.printStackTrace(); | |
210 | + } | |
211 | + //保存图片后发送广播通知更新数据库 | |
212 | + Uri uri = Uri.fromFile(savefile); | |
213 | + context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri)); | |
214 | + } | |
215 | + }).start(); | |
216 | + } | |
217 | + | |
218 | + /** | |
219 | + * 保存Bitmap到本机 | |
220 | + * | |
221 | + * @param context context | |
222 | + * @param fileName bitmap文件名 | |
223 | + * @param bmp bitmap | |
224 | + * @param saveResultCallback 保存结果callback | |
225 | + */ | |
226 | + public static void saveBitmap(final Context context, final String fileName, final Bitmap bmp, | |
227 | + final SaveResultCallback | |
228 | + saveResultCallback) { | |
229 | + new Thread(new Runnable() { | |
230 | + @Override | |
231 | + public void run() { | |
232 | + File appDir = new File(Environment.getExternalStorageDirectory(), "yizhi"); | |
233 | + if (!appDir.exists()) { | |
234 | + appDir.mkdir(); | |
235 | + } | |
236 | + // SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); | |
237 | + // 设置以当前时间格式为图片名称 | |
238 | + String saveFileName = MD5Utils.getMD5("yizhi_pic" + fileName) + ".png"; | |
239 | + saveFileName = saveFileName.substring(20);//取前20位作为SaveName | |
240 | + File file = new File(appDir, saveFileName); | |
241 | + try { | |
242 | + FileOutputStream fos = new FileOutputStream(file); | |
243 | + bmp.compress(Bitmap.CompressFormat.PNG, 100, fos); | |
244 | + fos.flush(); | |
245 | + fos.close(); | |
246 | + saveResultCallback.onSavedSuccess(); | |
247 | + } catch (FileNotFoundException e) { | |
248 | + saveResultCallback.onSavedFailed(); | |
249 | + e.printStackTrace(); | |
250 | + } catch (IOException e) { | |
251 | + saveResultCallback.onSavedFailed(); | |
252 | + e.printStackTrace(); | |
253 | + } | |
254 | + //保存图片后发送广播通知更新数据库 | |
255 | + Uri uri = Uri.fromFile(file); | |
256 | + context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri)); | |
257 | + } | |
258 | + }).start(); | |
259 | + } | |
260 | + | |
261 | + //保存webview缓存的 | |
262 | + public static String getCache() { | |
263 | + String cacheFilePath=Environment.getExternalStorageDirectory()+File.separator+"Cache"; | |
264 | + File cacheFile=new File(cacheFilePath); | |
265 | + if (!cacheFile.exists())cacheFile.mkdirs(); | |
266 | + return cacheFile.toString(); | |
267 | + } | |
268 | + | |
269 | + public static boolean webViewCacheIsExit(){ | |
270 | + File file=new File(getCache()); | |
271 | + FileInputStream fileInputStream=null; | |
272 | + try { | |
273 | + fileInputStream=new FileInputStream(file); | |
274 | + if (fileInputStream.available()>0) | |
275 | + return true; | |
276 | + } catch (FileNotFoundException e) { | |
277 | + e.printStackTrace(); | |
278 | + } catch (IOException e) { | |
279 | + e.printStackTrace(); | |
280 | + } | |
281 | + return false; | |
282 | + } | |
283 | + | |
284 | + public interface SaveResultCallback { | |
285 | + void onSavedSuccess(); | |
286 | + | |
287 | + void onSavedFailed(); | |
288 | + } | |
289 | +} | |
290 | + | |
291 | + | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/HtmlUtils.java
0 → 100644
... | ... | @@ -0,0 +1,93 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import java.util.List; | |
4 | + | |
5 | +/** | |
6 | + * Created by Horrarndoo on 2017/8/31. | |
7 | + * <p> | |
8 | + * Html工具类 | |
9 | + */ | |
10 | +public class HtmlUtils { | |
11 | + | |
12 | + //css样式,隐藏header | |
13 | + private static final String HIDE_HEADER_STYLE = "<style>div.headline{display:none;}</style>"; | |
14 | + | |
15 | + //css style tag,需要格式化 | |
16 | + private static final String NEEDED_FORMAT_CSS_TAG = "<link rel=\"stylesheet\" " + | |
17 | + "type=\"text/css\" href=\"%s\"/>"; | |
18 | + | |
19 | + // js script tag,需要格式化 | |
20 | + private static final String NEEDED_FORMAT_JS_TAG = "<script src=\"%s\"></script>"; | |
21 | + | |
22 | + public static final String MIME_TYPE = "text/html; charset=utf-8"; | |
23 | + | |
24 | + public static final String ENCODING = "utf-8"; | |
25 | + | |
26 | + private HtmlUtils() { | |
27 | + | |
28 | + } | |
29 | + | |
30 | + /** | |
31 | + * 根据css链接生成Link标签 | |
32 | + * | |
33 | + * @param url String | |
34 | + * @return String | |
35 | + */ | |
36 | + public static String createCssTag(String url) { | |
37 | + | |
38 | + return String.format(NEEDED_FORMAT_CSS_TAG, url); | |
39 | + } | |
40 | + | |
41 | + /** | |
42 | + * 根据多个css链接生成Link标签 | |
43 | + * | |
44 | + * @param urls List<String> | |
45 | + * @return String | |
46 | + */ | |
47 | + public static String createCssTag(List<String> urls) { | |
48 | + | |
49 | + final StringBuilder sb = new StringBuilder(); | |
50 | + for (String url : urls) { | |
51 | + sb.append(createCssTag(url)); | |
52 | + } | |
53 | + return sb.toString(); | |
54 | + } | |
55 | + | |
56 | + /** | |
57 | + * 根据js链接生成Script标签 | |
58 | + * | |
59 | + * @param url String | |
60 | + * @return String | |
61 | + */ | |
62 | + public static String createJsTag(String url) { | |
63 | + | |
64 | + return String.format(NEEDED_FORMAT_JS_TAG, url); | |
65 | + } | |
66 | + | |
67 | + /** | |
68 | + * 根据多个js链接生成Script标签 | |
69 | + * | |
70 | + * @param urls List<String> | |
71 | + * @return String | |
72 | + */ | |
73 | + public static String createJsTag(List<String> urls) { | |
74 | + | |
75 | + final StringBuilder sb = new StringBuilder(); | |
76 | + for (String url : urls) { | |
77 | + sb.append(createJsTag(url)); | |
78 | + } | |
79 | + return sb.toString(); | |
80 | + } | |
81 | + | |
82 | + /** | |
83 | + * 根据样式标签,html字符串,js标签 | |
84 | + * 生成完整的HTML文档 | |
85 | + */ | |
86 | + | |
87 | + public static String createHtmlData(String html, List<String> cssList, List<String> jsList) { | |
88 | + final String css = HtmlUtils.createCssTag(cssList); | |
89 | + final String js = HtmlUtils.createJsTag(jsList); | |
90 | + return css.concat(HIDE_HEADER_STYLE).concat(html).concat(js); | |
91 | + } | |
92 | +} | |
93 | + | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/HttpUtils.java
0 → 100644
... | ... | @@ -0,0 +1,76 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.os.Build; | |
4 | +import android.support.annotation.NonNull; | |
5 | +import android.webkit.WebSettings; | |
6 | + | |
7 | +import com.orhanobut.logger.Logger; | |
8 | + | |
9 | +import java.util.ArrayList; | |
10 | +import java.util.List; | |
11 | +import java.util.regex.Matcher; | |
12 | +import java.util.regex.Pattern; | |
13 | + | |
14 | +/** | |
15 | + * Created by Horrarndoo on 2017/9/18. | |
16 | + * <p> | |
17 | + * HttpUtils 主要用于获取UserAgent | |
18 | + */ | |
19 | + | |
20 | +public class HttpUtils { | |
21 | + /** | |
22 | + * 获取UserAgent | |
23 | + * | |
24 | + * @return UserAgent | |
25 | + */ | |
26 | + @NonNull | |
27 | + public static String getUserAgent() { | |
28 | + String userAgent = ""; | |
29 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { | |
30 | + try { | |
31 | + userAgent = WebSettings.getDefaultUserAgent(AppUtils.getContext()); | |
32 | + } catch (Exception e) { | |
33 | + userAgent = System.getProperty("http.agent"); | |
34 | + } | |
35 | + } else { | |
36 | + userAgent = System.getProperty("http.agent"); | |
37 | + } | |
38 | + StringBuffer sb = new StringBuffer(); | |
39 | + for (int i = 0, length = userAgent.length(); i < length; i++) { | |
40 | + char c = userAgent.charAt(i); | |
41 | + if (c <= '\u001f' || c >= '\u007f') { | |
42 | + sb.append(String.format("\\u%04x", (int) c)); | |
43 | + } else { | |
44 | + sb.append(c); | |
45 | + } | |
46 | + } | |
47 | + return sb.toString(); | |
48 | + } | |
49 | + | |
50 | + public static String makeUA() { | |
51 | + final String ua = Build.BRAND + "/" + Build.MODEL + "/" + Build.VERSION.RELEASE; | |
52 | + return ua; | |
53 | + } | |
54 | + | |
55 | + public static String[] returnImageUrlsFromHtml(String html) { | |
56 | + List<String> imageSrcList = new ArrayList<String>(); | |
57 | + Pattern p = Pattern.compile("<img\\b[^>]*\\bsrc\\b\\s*=\\s*('|\")?([^'\"\n\r\f>]+(\\" + | |
58 | + ".jpg|\\.bmp|\\.eps|\\.gif|\\.mif|\\.miff|\\.png|\\.tif|\\.tiff|\\.svg|\\.wmf|\\" + | |
59 | + ".jpe|\\.jpeg|\\.dib|\\.ico|\\.tga|\\.cut|\\.pic|\\b)\\b)[^>]*>", Pattern | |
60 | + .CASE_INSENSITIVE); | |
61 | + Matcher m = p.matcher(html); | |
62 | + String quote = null; | |
63 | + String src = null; | |
64 | + while (m.find()) { | |
65 | + quote = m.group(1); | |
66 | + src = (quote == null || quote.trim().length() == 0) ? m.group(2).split("//s+")[0] : m | |
67 | + .group(2); | |
68 | + imageSrcList.add(src); | |
69 | + } | |
70 | + if (imageSrcList.size() == 0) { | |
71 | + Logger.e("资讯中未匹配到图片链接"); | |
72 | + return null; | |
73 | + } | |
74 | + return imageSrcList.toArray(new String[imageSrcList.size()]); | |
75 | + } | |
76 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/IOUtils.java
0 → 100644
... | ... | @@ -0,0 +1,25 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import java.io.Closeable; | |
4 | +import java.io.IOException; | |
5 | + | |
6 | +/** | |
7 | + * Created by Horrarndoo on 2017/8/31. | |
8 | + * <p> | |
9 | + * IO流工具类 | |
10 | + */ | |
11 | +public class IOUtils { | |
12 | + /** | |
13 | + * 关闭流 | |
14 | + */ | |
15 | + public static boolean close(Closeable io) { | |
16 | + if (io != null) { | |
17 | + try { | |
18 | + io.close(); | |
19 | + } catch (IOException e) { | |
20 | + LogUtils.e(e); | |
21 | + } | |
22 | + } | |
23 | + return true; | |
24 | + } | |
25 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/ImageUtils.java
0 → 100644
... | ... | @@ -0,0 +1,339 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.annotation.TargetApi; | |
4 | +import android.app.Activity; | |
5 | +import android.content.ContentUris; | |
6 | +import android.content.ContentValues; | |
7 | +import android.content.Context; | |
8 | +import android.content.DialogInterface; | |
9 | +import android.content.Intent; | |
10 | +import android.database.Cursor; | |
11 | +import android.net.Uri; | |
12 | +import android.os.Build; | |
13 | +import android.os.Environment; | |
14 | +import android.provider.DocumentsContract; | |
15 | +import android.provider.MediaStore; | |
16 | +import android.support.v7.app.AlertDialog; | |
17 | + | |
18 | +import com.bumptech.glide.Glide; | |
19 | +import com.bumptech.glide.request.FutureTarget; | |
20 | + | |
21 | +import io.reactivex.Observable; | |
22 | +import io.reactivex.ObservableSource; | |
23 | +import io.reactivex.functions.Function; | |
24 | + | |
25 | +/** | |
26 | + * 图片工具类 | |
27 | + */ | |
28 | +public class ImageUtils { | |
29 | + | |
30 | + /** | |
31 | + * 拍照 | |
32 | + */ | |
33 | + public static final int REQUEST_CODE_FROM_CAMERA = 1 << 10; | |
34 | + | |
35 | + /** | |
36 | + * 相册 | |
37 | + */ | |
38 | + public static final int REQUEST_CODE_FROM_ALBUM = 1 << 12; | |
39 | + | |
40 | + /** | |
41 | + * 裁剪 | |
42 | + */ | |
43 | + public static final int REQUEST_CODE_CROP_IMAGE = 1 << 14; | |
44 | + | |
45 | + /** | |
46 | + * 存放拍照图片的uri地址 | |
47 | + */ | |
48 | + public static Uri imageUriFromCamera; | |
49 | + | |
50 | + /** | |
51 | + * 存放裁剪图片的uri地址 | |
52 | + */ | |
53 | + public static Uri cropImageUri; | |
54 | + | |
55 | + /** | |
56 | + * 显示获取照片不同方式对话框 | |
57 | + */ | |
58 | + public static void showImagePickDialog(final Activity activity) { | |
59 | + showImagePickDialog(activity, 0); | |
60 | + } | |
61 | + | |
62 | + /** | |
63 | + * 显示获取照片不同方式对话框 | |
64 | + */ | |
65 | + public static void showImagePickDialog(final Activity activity, final int addRequest) { | |
66 | + String title = "选择获取图片方式"; | |
67 | + String[] items = new String[]{"拍照", "相册"}; | |
68 | + new AlertDialog.Builder(activity) | |
69 | + .setTitle(title) | |
70 | + .setItems(items, new DialogInterface.OnClickListener() { | |
71 | + @Override | |
72 | + public void onClick(DialogInterface dialog, int which) { | |
73 | + dialog.dismiss(); | |
74 | + switch (which) { | |
75 | + case 0: | |
76 | + pickImageFromCamera(activity, addRequest); | |
77 | + break; | |
78 | + case 1: | |
79 | + pickImageFromAlbum(activity, addRequest); | |
80 | + break; | |
81 | + default: | |
82 | + break; | |
83 | + } | |
84 | + } | |
85 | + }) | |
86 | + .setNegativeButton("取消", null) | |
87 | + .show(); | |
88 | + } | |
89 | + | |
90 | + /** | |
91 | + * 打开相机拍照获取图片 | |
92 | + */ | |
93 | + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) | |
94 | + public static void pickImageFromCamera(final Activity activity, int addRequest) { | |
95 | + // 先生成一个uri地址用于存放拍照获取的图片 | |
96 | + imageUriFromCamera = createImageUri(activity); | |
97 | + | |
98 | + Intent intent = new Intent(); | |
99 | + intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); | |
100 | + intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUriFromCamera); | |
101 | + activity.startActivityForResult(intent, REQUEST_CODE_FROM_CAMERA + addRequest); | |
102 | + } | |
103 | + | |
104 | + /** | |
105 | + * 打开相机拍照获取图片 | |
106 | + */ | |
107 | + public static void pickImageFromCamera(final Activity activity) { | |
108 | + pickImageFromCamera(activity, 0); | |
109 | + } | |
110 | + | |
111 | + /** | |
112 | + * 打开本地相册选取图片 | |
113 | + */ | |
114 | + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) | |
115 | + public static void pickImageFromAlbum(final Activity activity, int addRequest) { | |
116 | + Intent intent = new Intent(); | |
117 | + intent.setAction(Intent.ACTION_GET_CONTENT); | |
118 | + intent.setType("image/*"); | |
119 | + activity.startActivityForResult(intent, REQUEST_CODE_FROM_ALBUM + addRequest); | |
120 | + } | |
121 | + | |
122 | + /** | |
123 | + * 打开本地相册选取图片 | |
124 | + */ | |
125 | + public static void pickImageFromAlbum(final Activity activity) { | |
126 | + pickImageFromAlbum(activity, 0); | |
127 | + } | |
128 | + | |
129 | + /** | |
130 | + * 压缩图片 | |
131 | + * | |
132 | + * @param context context | |
133 | + * @param uri 图片uri | |
134 | + * @param reqW 上传图片需要压缩的宽度 | |
135 | + * @param reqH 上传图片需要压缩的高度 | |
136 | + * @return 上传成功回调 | |
137 | + */ | |
138 | + public static Observable<byte[]> compressImage(final Context context, | |
139 | + Uri uri, | |
140 | + final int reqW, | |
141 | + final int reqH) { | |
142 | + // 先从本地获取图片,利用Glide压缩图片后获取byte[] | |
143 | + return Observable.just(uri) | |
144 | + .flatMap(new Function<Uri, ObservableSource<byte[]>>() { | |
145 | + @Override | |
146 | + public ObservableSource<byte[]> apply(Uri uri) throws Exception { | |
147 | + // 在work线程中,同步压缩图片,然后Observable返回 | |
148 | + // 即将Glide的回调封装成RxJava的Observable | |
149 | + FutureTarget<byte[]> future = Glide.with(context) | |
150 | + .load(uri) | |
151 | + .asBitmap() | |
152 | + .toBytes() | |
153 | + .into(reqW, reqH); | |
154 | + | |
155 | + byte[] bytes; | |
156 | + try { | |
157 | + bytes = future.get(); | |
158 | + } catch (Exception e) { | |
159 | + // 获取失败时,抛出runtime异常 | |
160 | + // 该异常会被Subscriber捕捉,进onError | |
161 | + throw new RuntimeException(e); | |
162 | + } | |
163 | + return Observable.just(bytes); | |
164 | + } | |
165 | + }); | |
166 | + } | |
167 | + | |
168 | + /** | |
169 | + * 图片裁剪 | |
170 | + */ | |
171 | + public static void cropImage(Activity activity, Uri srcUri) { | |
172 | + cropImageUri = createImageUri(activity); | |
173 | + | |
174 | + Intent intent = new Intent("com.android.camera.action.CROP"); | |
175 | + intent.setDataAndType(srcUri, "image/*"); | |
176 | + intent.putExtra("crop", "true"); | |
177 | + | |
178 | + //////////////////////////////////////////////////////////////// | |
179 | + // 1.宽高和比例都不设置时,裁剪框可以自行调整(比例和大小都可以随意调整) | |
180 | + //////////////////////////////////////////////////////////////// | |
181 | + // 2.只设置裁剪框宽高比(aspect)后,裁剪框比例固定不可调整,只能调整大小 | |
182 | + ///////////////////////////////// | |
183 | + // 3.裁剪后生成图片宽高(output)的设置和裁剪框无关,只决定最终生成图片大小 | |
184 | + //////////////////////////////////////////////////////////////// | |
185 | + // 4.裁剪框宽高比例(aspect)可以和裁剪后生成图片比例(output)不同,此时, | |
186 | + // 会以裁剪框的宽为准,按照裁剪宽高比例生成一个图片,该图和框选部分可能不同, | |
187 | + // 不同的情况可能是截取框选的一部分,也可能超出框选部分,向下延伸补足 | |
188 | + //////////////////////////////////////////////////////////////// | |
189 | + | |
190 | + // aspectX aspectY 是裁剪框宽高的比例 | |
191 | + intent.putExtra("aspectX", 1); | |
192 | + intent.putExtra("aspectY", 1); | |
193 | + // outputX outputY 是裁剪后生成图片的宽高 | |
194 | + // intent.putExtra("outputX", 300); | |
195 | + // intent.putExtra("outputY", 100); | |
196 | + | |
197 | + // return-data为true时,会直接返回bitmap数据,但是大图裁剪时会出现OOM,推荐下面为false时的方式 | |
198 | + // return-data为false时,不会返回bitmap,但需要指定一个MediaStore.EXTRA_OUTPUT保存图片uri | |
199 | + intent.putExtra("return-data", false); | |
200 | + intent.putExtra(MediaStore.EXTRA_OUTPUT, cropImageUri); | |
201 | + | |
202 | + activity.startActivityForResult(intent, REQUEST_CODE_CROP_IMAGE); | |
203 | + } | |
204 | + | |
205 | + /** | |
206 | + * 创建一条图片uri,用于保存拍照后的照片 | |
207 | + */ | |
208 | + private static Uri createImageUri(Context context) { | |
209 | + String name = "boreImg" + System.currentTimeMillis(); | |
210 | + ContentValues values = new ContentValues(); | |
211 | + values.put(MediaStore.Images.Media.TITLE, name); | |
212 | + values.put(MediaStore.Images.Media.DISPLAY_NAME, name + ".jpeg"); | |
213 | + values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); | |
214 | + Uri uri = context.getContentResolver().insert(MediaStore.Images.Media | |
215 | + .EXTERNAL_CONTENT_URI, values); | |
216 | + return uri; | |
217 | + } | |
218 | + | |
219 | + /** | |
220 | + * 删除一条图片 | |
221 | + */ | |
222 | + public static void deleteImageUri(Context context, Uri uri) { | |
223 | + context.getContentResolver().delete(uri, null, null); | |
224 | + } | |
225 | + | |
226 | + /** | |
227 | + * 用第三方应用app打开图片 | |
228 | + */ | |
229 | + public static void openImageByOtherApp(Context context, Uri imageUri) { | |
230 | + Intent intent = new Intent(); | |
231 | + intent.setAction(Intent.ACTION_VIEW); | |
232 | + intent.setDataAndType(imageUri, "image/*"); | |
233 | + context.startActivity(intent); | |
234 | + } | |
235 | + | |
236 | + /** | |
237 | + * 根据Uri获取图片绝对路径,解决Android4.4以上版本Uri转换 | |
238 | + */ | |
239 | + public static String getImageAbsolutePath19(Context context, Uri imageUri) { | |
240 | + if (context == null || imageUri == null) | |
241 | + return null; | |
242 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT | |
243 | + && DocumentsContract.isDocumentUri(context, imageUri)) { | |
244 | + if (isExternalStorageDocument(imageUri)) { | |
245 | + String docId = DocumentsContract.getDocumentId(imageUri); | |
246 | + String[] split = docId.split(":"); | |
247 | + String type = split[0]; | |
248 | + if ("primary".equalsIgnoreCase(type)) { | |
249 | + return Environment.getExternalStorageDirectory() + "/" + split[1]; | |
250 | + } | |
251 | + } else if (isDownloadsDocument(imageUri)) { | |
252 | + String id = DocumentsContract.getDocumentId(imageUri); | |
253 | + Uri contentUri = ContentUris.withAppendedId(Uri.parse | |
254 | + ("content://downloads/public_downloads"), Long.valueOf(id)); | |
255 | + return getDataColumn(context, contentUri, null, null); | |
256 | + } else if (isMediaDocument(imageUri)) { | |
257 | + String docId = DocumentsContract.getDocumentId(imageUri); | |
258 | + String[] split = docId.split(":"); | |
259 | + String type = split[0]; | |
260 | + Uri contentUri = null; | |
261 | + if ("image".equals(type)) { | |
262 | + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; | |
263 | + } else if ("video".equals(type)) { | |
264 | + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; | |
265 | + } else if ("audio".equals(type)) { | |
266 | + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; | |
267 | + } | |
268 | + String selection = MediaStore.Images.Media._ID + "=?"; | |
269 | + String[] selectionArgs = new String[]{split[1]}; | |
270 | + return getDataColumn(context, contentUri, selection, selectionArgs); | |
271 | + } | |
272 | + } | |
273 | + | |
274 | + // MediaStore (and general) | |
275 | + if ("content".equalsIgnoreCase(imageUri.getScheme())) { | |
276 | + // Return the remote address | |
277 | + if (isGooglePhotosUri(imageUri)) | |
278 | + return imageUri.getLastPathSegment(); | |
279 | + return getDataColumn(context, imageUri, null, null); | |
280 | + } | |
281 | + // File | |
282 | + else if ("file".equalsIgnoreCase(imageUri.getScheme())) { | |
283 | + return imageUri.getPath(); | |
284 | + } | |
285 | + return null; | |
286 | + } | |
287 | + | |
288 | + private static String getDataColumn(Context context, Uri uri, String selection, String[] | |
289 | + selectionArgs) { | |
290 | + Cursor cursor = null; | |
291 | + String column = MediaStore.Images.Media.DATA; | |
292 | + String[] projection = {column}; | |
293 | + try { | |
294 | + cursor = context.getContentResolver().query(uri, projection, selection, | |
295 | + selectionArgs, null); | |
296 | + if (cursor != null && cursor.moveToFirst()) { | |
297 | + int index = cursor.getColumnIndexOrThrow(column); | |
298 | + return cursor.getString(index); | |
299 | + } | |
300 | + } finally { | |
301 | + if (cursor != null) | |
302 | + cursor.close(); | |
303 | + } | |
304 | + return null; | |
305 | + } | |
306 | + | |
307 | + /** | |
308 | + * @param uri The Uri to check. | |
309 | + * @return Whether the Uri authority is ExternalStorageProvider. | |
310 | + */ | |
311 | + private static boolean isExternalStorageDocument(Uri uri) { | |
312 | + return "com.android.externalstorage.documents".equals(uri.getAuthority()); | |
313 | + } | |
314 | + | |
315 | + /** | |
316 | + * @param uri The Uri to check. | |
317 | + * @return Whether the Uri authority is DownloadsProvider. | |
318 | + */ | |
319 | + private static boolean isDownloadsDocument(Uri uri) { | |
320 | + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); | |
321 | + } | |
322 | + | |
323 | + /** | |
324 | + * @param uri The Uri to check. | |
325 | + * @return Whether the Uri authority is MediaProvider. | |
326 | + */ | |
327 | + private static boolean isMediaDocument(Uri uri) { | |
328 | + return "com.android.providers.media.documents".equals(uri.getAuthority()); | |
329 | + } | |
330 | + | |
331 | + /** | |
332 | + * @param uri The Uri to check. | |
333 | + * @return Whether the Uri authority is Google Photos. | |
334 | + */ | |
335 | + private static boolean isGooglePhotosUri(Uri uri) { | |
336 | + return "com.google.android.apps.photos.content".equals(uri.getAuthority()); | |
337 | + } | |
338 | + | |
339 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/JsonUtils.java
0 → 100644
... | ... | @@ -0,0 +1,65 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import com.google.gson.Gson; | |
4 | +import com.google.gson.JsonObject; | |
5 | +import com.google.gson.JsonSyntaxException; | |
6 | + | |
7 | +import java.lang.reflect.Type; | |
8 | + | |
9 | +/** | |
10 | + * Created by Horrarndoo on 2017/9/20. | |
11 | + * <p> | |
12 | + * Json转换工具类 | |
13 | + */ | |
14 | +public class JsonUtils { | |
15 | + | |
16 | + private static Gson mGson = new Gson(); | |
17 | + | |
18 | + /** | |
19 | + * 将对象准换为json字符串 | |
20 | + * | |
21 | + * @param object | |
22 | + * @param <T> | |
23 | + * @return | |
24 | + */ | |
25 | + public static <T> String serialize(T object) { | |
26 | + return mGson.toJson(object); | |
27 | + } | |
28 | + | |
29 | + /** | |
30 | + * 将json字符串转换为对象 | |
31 | + * | |
32 | + * @param json | |
33 | + * @param clz | |
34 | + * @param <T> | |
35 | + * @return | |
36 | + */ | |
37 | + public static <T> T deserialize(String json, Class<T> clz) throws JsonSyntaxException { | |
38 | + return mGson.fromJson(json, clz); | |
39 | + } | |
40 | + | |
41 | + /** | |
42 | + * 将json对象转换为实体对象 | |
43 | + * | |
44 | + * @param json | |
45 | + * @param clz | |
46 | + * @param <T> | |
47 | + * @return | |
48 | + * @throws JsonSyntaxException | |
49 | + */ | |
50 | + public static <T> T deserialize(JsonObject json, Class<T> clz) throws JsonSyntaxException { | |
51 | + return mGson.fromJson(json, clz); | |
52 | + } | |
53 | + | |
54 | + /** | |
55 | + * 将json字符串转换为对象 | |
56 | + * | |
57 | + * @param json | |
58 | + * @param type | |
59 | + * @param <T> | |
60 | + * @return | |
61 | + */ | |
62 | + public static <T> T deserialize(String json, Type type) throws JsonSyntaxException { | |
63 | + return mGson.fromJson(json, type); | |
64 | + } | |
65 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/LogUtils.java
0 → 100644
... | ... | @@ -0,0 +1,168 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.util.Log; | |
4 | + | |
5 | + | |
6 | +/** | |
7 | + * Created by Horrarndoo on 2017/4/5. | |
8 | + * <p> | |
9 | + * Log工具类 | |
10 | + */ | |
11 | +public class LogUtils { | |
12 | + /** | |
13 | + * 日志输出级别NONE | |
14 | + */ | |
15 | + public static final int LEVEL_NONE = 0; | |
16 | + /** | |
17 | + * 日志输出级别E | |
18 | + */ | |
19 | + public static final int LEVEL_ERROR = 1; | |
20 | + /** | |
21 | + * 日志输出级别W | |
22 | + */ | |
23 | + public static final int LEVEL_WARN = 2; | |
24 | + /** | |
25 | + * 日志输出级别I | |
26 | + */ | |
27 | + public static final int LEVEL_INFO = 3; | |
28 | + /** | |
29 | + * 日志输出级别D | |
30 | + */ | |
31 | + public static final int LEVEL_DEBUG = 4; | |
32 | + /** | |
33 | + * 日志输出级别V | |
34 | + */ | |
35 | + public static final int LEVEL_VERBOSE = 5; | |
36 | + | |
37 | + /** | |
38 | + * 日志输出时的TAG | |
39 | + */ | |
40 | + private static String mTag = "LogUtils"; | |
41 | + | |
42 | + /** | |
43 | + * 是否允许输出log | |
44 | + */ | |
45 | + private static int mDebuggable = LEVEL_VERBOSE; | |
46 | + | |
47 | + /** | |
48 | + * 设置调试Log开关 | |
49 | + * | |
50 | + * @param isEnable 是否允许log | |
51 | + */ | |
52 | + public static void setDebuggable(boolean isEnable) { | |
53 | + mDebuggable = isEnable ? LEVEL_VERBOSE : LEVEL_NONE; | |
54 | + } | |
55 | + | |
56 | + /** | |
57 | + * 以级别为 d 的形式输出LOG | |
58 | + */ | |
59 | + public static void v(String msg) { | |
60 | + if (mDebuggable >= LEVEL_VERBOSE) { | |
61 | + Log.v(mTag, msg); | |
62 | + } | |
63 | + } | |
64 | + | |
65 | + /** | |
66 | + * 以级别为 d 的形式输出LOG | |
67 | + */ | |
68 | + public static void d(String msg) { | |
69 | + if (mDebuggable >= LEVEL_DEBUG) { | |
70 | + Log.d(mTag, msg); | |
71 | + } | |
72 | + } | |
73 | + | |
74 | + /** | |
75 | + * 以级别为 i 的形式输出LOG | |
76 | + */ | |
77 | + public static void i(String msg) { | |
78 | + if (mDebuggable >= LEVEL_INFO) { | |
79 | + Log.i(mTag, msg); | |
80 | + } | |
81 | + } | |
82 | + | |
83 | + /** | |
84 | + * 以级别为 w 的形式输出LOG | |
85 | + */ | |
86 | + public static void w(String msg) { | |
87 | + if (mDebuggable >= LEVEL_WARN) { | |
88 | + Log.w(mTag, msg); | |
89 | + } | |
90 | + } | |
91 | + | |
92 | + /** | |
93 | + * 以级别为 e 的形式输出LOG | |
94 | + */ | |
95 | + public static void e(String msg) { | |
96 | + if (mDebuggable >= LEVEL_ERROR) { | |
97 | + Log.e(mTag, msg); | |
98 | + } | |
99 | + } | |
100 | + | |
101 | + /** | |
102 | + * 以级别为 w 的形式输出Throwable | |
103 | + */ | |
104 | + public static void w(Throwable tr) { | |
105 | + w("", tr); | |
106 | + } | |
107 | + | |
108 | + /** | |
109 | + * 以级别为 w 的形式输出LOG信息和Throwable | |
110 | + */ | |
111 | + public static void w(String msg, Throwable tr) { | |
112 | + Log.w(mTag, msg, tr); | |
113 | + } | |
114 | + | |
115 | + /** | |
116 | + * 以级别为 e 的形式输出Throwable | |
117 | + */ | |
118 | + public static void e(Throwable tr) { | |
119 | + e("", tr); | |
120 | + } | |
121 | + | |
122 | + /** | |
123 | + * 以级别为 e 的形式输出LOG信息和Throwable | |
124 | + */ | |
125 | + public static void e(String msg, Throwable tr) { | |
126 | + if (mDebuggable >= LEVEL_ERROR && null != msg) { | |
127 | + Log.e(mTag, msg, tr); | |
128 | + } | |
129 | + } | |
130 | + | |
131 | + private static int originStackIndex = 2; | |
132 | + | |
133 | + /** | |
134 | + * 获取当前方法所在的文件名 | |
135 | + * | |
136 | + * @return 当前方法所在的文件名 | |
137 | + */ | |
138 | + public static String getFileName() { | |
139 | + return Thread.currentThread().getStackTrace()[originStackIndex].getFileName(); | |
140 | + } | |
141 | + | |
142 | + /** | |
143 | + * 获取当前方法所在的Class名 | |
144 | + * | |
145 | + * @return 当前方法所在的Class名 | |
146 | + */ | |
147 | + public static String getClassName() { | |
148 | + return Thread.currentThread().getStackTrace()[originStackIndex].getClassName(); | |
149 | + } | |
150 | + | |
151 | + /** | |
152 | + * 获取当前方法名 | |
153 | + * | |
154 | + * @return 当前方法名 | |
155 | + */ | |
156 | + public static String getMethodName() { | |
157 | + return Thread.currentThread().getStackTrace()[originStackIndex].getMethodName(); | |
158 | + } | |
159 | + | |
160 | + /** | |
161 | + * 获取当前代码执行处行数 | |
162 | + * | |
163 | + * @return 当前代码执行处行数 | |
164 | + */ | |
165 | + public static int getLineNumber() { | |
166 | + return Thread.currentThread().getStackTrace()[originStackIndex].getLineNumber(); | |
167 | + } | |
168 | +} | |
0 | 169 | \ No newline at end of file | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/MD5Utils.java
0 → 100644
... | ... | @@ -0,0 +1,38 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import java.security.MessageDigest; | |
4 | + | |
5 | +/** | |
6 | + * Created by Horrarndoo on 2017/4/5. | |
7 | + * <p> | |
8 | + * MD5加密工具类 | |
9 | + */ | |
10 | +public class MD5Utils { | |
11 | + /* | |
12 | + * MD5加密,32位 | |
13 | + */ | |
14 | + public static String getMD5(String str) { | |
15 | + MessageDigest md5 = null; | |
16 | + try { | |
17 | + md5 = MessageDigest.getInstance("MD5"); | |
18 | + } catch (Exception e) { | |
19 | + e.printStackTrace(); | |
20 | + return ""; | |
21 | + } | |
22 | + char[] charArray = str.toCharArray(); | |
23 | + byte[] byteArray = new byte[charArray.length]; | |
24 | + for (int i = 0; i < charArray.length; i++) { | |
25 | + byteArray[i] = (byte) charArray[i]; | |
26 | + } | |
27 | + byte[] md5Bytes = md5.digest(byteArray); | |
28 | + StringBuffer hexValue = new StringBuffer(); | |
29 | + for (int i = 0; i < md5Bytes.length; i++) { | |
30 | + int val = ((int) md5Bytes[i]) & 0xff; | |
31 | + if (val < 16) { | |
32 | + hexValue.append("0"); | |
33 | + } | |
34 | + hexValue.append(Integer.toHexString(val)); | |
35 | + } | |
36 | + return hexValue.toString(); | |
37 | + } | |
38 | +} | |
0 | 39 | \ No newline at end of file | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/NavigationUtils.java
0 → 100644
... | ... | @@ -0,0 +1,23 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.support.design.internal.NavigationMenuView; | |
4 | +import android.support.design.widget.NavigationView; | |
5 | + | |
6 | +/** | |
7 | + * Created by Horrarndoo on 2017/12/12. | |
8 | + * <p> | |
9 | + * NavigationView utils | |
10 | + */ | |
11 | + | |
12 | +public class NavigationUtils { | |
13 | + | |
14 | + public static void disableNavigationViewScrollbars(NavigationView navigationView) { | |
15 | + if (navigationView != null) { | |
16 | + NavigationMenuView navigationMenuView = (NavigationMenuView) navigationView | |
17 | + .getChildAt(0); | |
18 | + if (navigationMenuView != null) { | |
19 | + navigationMenuView.setVerticalScrollBarEnabled(false); | |
20 | + } | |
21 | + } | |
22 | + } | |
23 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/NetworkConnectionUtils.java
0 → 100644
... | ... | @@ -0,0 +1,236 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | +import android.content.ComponentName; | |
5 | +import android.content.Context; | |
6 | +import android.content.Intent; | |
7 | +import android.net.ConnectivityManager; | |
8 | +import android.net.NetworkInfo; | |
9 | +import android.net.wifi.ScanResult; | |
10 | +import android.net.wifi.WifiConfiguration; | |
11 | +import android.net.wifi.WifiConfiguration.KeyMgmt; | |
12 | +import android.net.wifi.WifiManager; | |
13 | +import android.os.Build; | |
14 | + | |
15 | +import java.io.IOException; | |
16 | +import java.util.List; | |
17 | + | |
18 | +import static com.share.mvpsdk.utils.LogUtils.e; | |
19 | + | |
20 | +/** | |
21 | + * Created by Horrarndoo on 2017/8/31. | |
22 | + * <p> | |
23 | + * Wifi连接工具类 | |
24 | + */ | |
25 | +public class NetworkConnectionUtils { | |
26 | + private final static String TAG = "NetworkConnectionUtils"; | |
27 | + | |
28 | + public NetworkConnectionUtils() { | |
29 | + } | |
30 | + | |
31 | + /** | |
32 | + * 连接指定 | |
33 | + * | |
34 | + * @param manager | |
35 | + * @param wifiSSID | |
36 | + * @return | |
37 | + */ | |
38 | + public static boolean connectToSocketWifi(WifiManager manager, String wifiSSID) { | |
39 | + LogUtils.i("要连接的socket wifi====>" + wifiSSID); | |
40 | + WifiConfiguration wifiConfiguration = new WifiConfiguration(); | |
41 | + wifiConfiguration.SSID = "\"" + wifiSSID + "\""; | |
42 | + wifiConfiguration.allowedKeyManagement.set(KeyMgmt.NONE); | |
43 | + wifiConfiguration.wepKeys[0] = "\"" + "\""; //小米手机MIUI7/华为EMUI4.1 需要webKey | |
44 | + | |
45 | + int networkId = manager.addNetwork(wifiConfiguration); | |
46 | + | |
47 | + if (networkId != -1) { | |
48 | + manager.enableNetwork(networkId, true); | |
49 | + e("连接设备成功"); | |
50 | + return true; | |
51 | + } else { | |
52 | + e("第一次连接失败,尝试第二次。"); | |
53 | + WifiConfiguration wifiConfiguration2 = new WifiConfiguration(); | |
54 | + wifiConfiguration2.SSID = "\"" + wifiSSID + "\""; | |
55 | + //wifiConfiguration.wepKeys[0] = "\"" + "\"";//去掉webKey //小米手机MIUI8不能有webKey | |
56 | + wifiConfiguration2.allowedKeyManagement.set(KeyMgmt.NONE); | |
57 | + networkId = manager.addNetwork(wifiConfiguration2); | |
58 | + if (networkId != -1) { | |
59 | + manager.enableNetwork(networkId, true); | |
60 | + e("连接设备成功"); | |
61 | + return true; | |
62 | + } | |
63 | + e("连接设备失败"); | |
64 | + } | |
65 | + return false; | |
66 | + } | |
67 | + | |
68 | + /** | |
69 | + * 获取要连接的wifi节点各个配置选项的加密类型 | |
70 | + * | |
71 | + * @param ssid | |
72 | + * @return wifiConfiguration | |
73 | + */ | |
74 | + public static WifiConfiguration getWifiConfiguration(WifiManager manager, String ssid, String | |
75 | + password) { | |
76 | + WifiConfiguration wifiConfiguration = new WifiConfiguration(); | |
77 | + wifiConfiguration.SSID = "\"" + ssid + "\""; | |
78 | + | |
79 | + List<ScanResult> list = manager.getScanResults(); | |
80 | + for (ScanResult scResult : list) { | |
81 | + if (ssid.equals(scResult.SSID)) { | |
82 | + String capabilities = scResult.capabilities; | |
83 | + LogUtils.i("capabilities=" + capabilities); | |
84 | + if (capabilities.contains("WEP") || capabilities.contains("wep")) { | |
85 | + wifiConfiguration.allowedKeyManagement.set(KeyMgmt.WPA_EAP); | |
86 | + wifiConfiguration.preSharedKey = "\"" + password + "\""; | |
87 | + LogUtils.i("wep"); | |
88 | + } else if (capabilities.contains("WPA") || capabilities.contains("wpa")) { | |
89 | + wifiConfiguration.allowedKeyManagement.set(KeyMgmt.WPA_PSK); | |
90 | + wifiConfiguration.preSharedKey = "\"" + password + "\""; | |
91 | + LogUtils.i("wpa"); | |
92 | + } else { | |
93 | + wifiConfiguration.allowedKeyManagement.set(KeyMgmt.NONE); | |
94 | + LogUtils.i("none"); | |
95 | + } | |
96 | + } | |
97 | + } | |
98 | + return wifiConfiguration; | |
99 | + } | |
100 | + | |
101 | + /** | |
102 | + * 给温控器成功发送联网命令后,连接温控器连接的wifi节点 | |
103 | + * | |
104 | + * @param context 上下文对象 | |
105 | + * @param ssid ssid | |
106 | + * @param password 密码 | |
107 | + */ | |
108 | + public static void connectWifiSSID(Context context, WifiManager manager, String ssid, String | |
109 | + password) { | |
110 | + e("reSetNetwork----------连接设备连入的路由---" + ssid); | |
111 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |
112 | + e("当前手机系统>=Android6.0,采取兼容模式"); | |
113 | + new WifiAutoConnectManager(manager).connect(ssid, password, WifiAutoConnectManager | |
114 | + .getCipherType(context, ssid)); | |
115 | + } else { | |
116 | + int networkId = manager.addNetwork(getWifiConfiguration(manager, ssid, password)); | |
117 | + if (networkId != -1) { | |
118 | + manager.enableNetwork(networkId, true); | |
119 | + } | |
120 | + } | |
121 | + } | |
122 | + | |
123 | + /** | |
124 | + * 格式化RouterSSID | |
125 | + * | |
126 | + * @param strRouterSSID 要格式化的当前连接的路由ssid | |
127 | + * @return 去除"\"后的RouterSSID字符串 | |
128 | + */ | |
129 | + public static String formatRouterSSID(String strRouterSSID) { | |
130 | + //e("formate routerSSID before---" + strRouterSSID); | |
131 | + if (strRouterSSID.contains("\"")) { | |
132 | + strRouterSSID = strRouterSSID.replaceAll("\"", ""); | |
133 | + //e("formate routerSSID after---" + strRouterSSID); | |
134 | + } | |
135 | + return strRouterSSID; | |
136 | + } | |
137 | + | |
138 | + /** | |
139 | + * Ping | |
140 | + * 用于确定手机是否已经连接上指定设备ip地址 | |
141 | + */ | |
142 | + public static boolean pingTest(String IPOrDomainName) { | |
143 | + | |
144 | + boolean isSuccess = false; | |
145 | + int status; | |
146 | + String result = "failed"; | |
147 | + Process p; | |
148 | + try { | |
149 | + p = Runtime.getRuntime().exec("ping -c 1 " + IPOrDomainName);// | |
150 | + // m_strForNetAddress是输入的网址或者Ip地址 | |
151 | + status = p.waitFor();// status 只能获取是否成功,无法获取更多的信息 | |
152 | + | |
153 | + if (status == 0) { | |
154 | + result = "success"; | |
155 | + isSuccess = true; | |
156 | + } | |
157 | + | |
158 | + } catch (IOException | InterruptedException e) { | |
159 | + e(e); | |
160 | + } | |
161 | + LogUtils.d("Ping result = " + result); | |
162 | + return isSuccess; | |
163 | + } | |
164 | + | |
165 | + /** | |
166 | + * 判断网络是否连接 | |
167 | + */ | |
168 | + public static boolean isConnected(Context context) { | |
169 | + ConnectivityManager cm = (ConnectivityManager) | |
170 | + context.getSystemService(Context.CONNECTIVITY_SERVICE); | |
171 | + | |
172 | + if (null == cm) { | |
173 | + return false; | |
174 | + } | |
175 | + | |
176 | + NetworkInfo info = cm.getActiveNetworkInfo(); | |
177 | + if (null != info && info.isConnected()) { | |
178 | + if (info.getState() == NetworkInfo.State.CONNECTED) { | |
179 | + return true; | |
180 | + } | |
181 | + } | |
182 | + return false; | |
183 | + } | |
184 | + | |
185 | + /** | |
186 | + * 判断是否有网络 | |
187 | + * | |
188 | + * @return 返回值 | |
189 | + */ | |
190 | + public static boolean isNetworkConnected(Context context) { | |
191 | + if (context != null) { | |
192 | + ConnectivityManager mConnectivityManager = (ConnectivityManager) context | |
193 | + .getSystemService(Context.CONNECTIVITY_SERVICE); | |
194 | + NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo(); | |
195 | + | |
196 | + if (mNetworkInfo != null) { | |
197 | + return mNetworkInfo.isAvailable(); | |
198 | + } | |
199 | + } | |
200 | + return false; | |
201 | + } | |
202 | + | |
203 | + /** | |
204 | + * 判断是否是wifi连接 | |
205 | + */ | |
206 | + public static boolean isWifi(Context context) { | |
207 | + ConnectivityManager cm = (ConnectivityManager) | |
208 | + context.getSystemService(Context.CONNECTIVITY_SERVICE); | |
209 | + | |
210 | + if (null == cm) { | |
211 | + return false; | |
212 | + } | |
213 | + | |
214 | + NetworkInfo info = cm.getActiveNetworkInfo(); | |
215 | + if (null != info) { | |
216 | + if (info.getType() == ConnectivityManager.TYPE_WIFI) { | |
217 | + return true; | |
218 | + } | |
219 | + } | |
220 | + return false; | |
221 | + | |
222 | + } | |
223 | + | |
224 | + | |
225 | + /** | |
226 | + * 打开网络设置界面 | |
227 | + */ | |
228 | + public static void openSetting(Activity activity, int requestCode) { | |
229 | + Intent intent = new Intent("/"); | |
230 | + ComponentName cm = new ComponentName("com.android.settings", | |
231 | + "com.android.settings.WirelessSettings"); | |
232 | + intent.setComponent(cm); | |
233 | + intent.setAction(Intent.ACTION_VIEW); | |
234 | + activity.startActivityForResult(intent, requestCode); | |
235 | + } | |
236 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/OkHttpExceptionUtil.java
0 → 100644
... | ... | @@ -0,0 +1,28 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.support.annotation.NonNull; | |
4 | + | |
5 | +import org.json.JSONObject; | |
6 | + | |
7 | +import okhttp3.ResponseBody; | |
8 | +import retrofit2.HttpException; | |
9 | +import retrofit2.Response; | |
10 | + | |
11 | +/** | |
12 | + * Created by 10501 on 2017/7/18. | |
13 | + */ | |
14 | + | |
15 | +public class OkHttpExceptionUtil { | |
16 | + public static void handOkHttpException(@NonNull HttpException e){ | |
17 | + Response response = e.response(); | |
18 | + if (response==null)return; | |
19 | + ResponseBody responseBody = response.errorBody(); | |
20 | + if (responseBody==null)return; | |
21 | + try { | |
22 | + JSONObject json = new JSONObject(responseBody.string()); | |
23 | + ToastUtils.showToast(json.optString("message")+"json="+json); | |
24 | + } catch (Exception e1) { | |
25 | + e1.printStackTrace(); | |
26 | + } | |
27 | + } | |
28 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/PermissionUtils.java
0 → 100644
... | ... | @@ -0,0 +1,323 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.Manifest; | |
4 | +import android.app.Activity; | |
5 | +import android.app.AlertDialog; | |
6 | +import android.content.DialogInterface; | |
7 | +import android.content.Intent; | |
8 | +import android.content.pm.PackageManager; | |
9 | +import android.net.Uri; | |
10 | +import android.provider.Settings; | |
11 | +import android.support.annotation.NonNull; | |
12 | +import android.support.v4.app.ActivityCompat; | |
13 | +import android.util.Log; | |
14 | +import android.widget.Toast; | |
15 | + | |
16 | + | |
17 | +import com.share.mvpsdk.R; | |
18 | + | |
19 | +import java.util.ArrayList; | |
20 | +import java.util.HashMap; | |
21 | +import java.util.List; | |
22 | +import java.util.Map; | |
23 | + | |
24 | +/** | |
25 | + * Created by ToaHanDong on 2017/11/3. | |
26 | + */ | |
27 | + | |
28 | +public class PermissionUtils { | |
29 | + private static final String TAG = PermissionUtils.class.getSimpleName(); | |
30 | + public static final int CODE_RECORD_AUDIO = 0; | |
31 | + public static final int CODE_GET_ACCOUNTS = 1; | |
32 | + public static final int CODE_READ_PHONE_STATE = 2; | |
33 | + public static final int CODE_CALL_PHONE = 3; | |
34 | + public static final int CODE_CAMERA = 4; | |
35 | + public static final int CODE_ACCESS_FINE_LOCATION = 5; | |
36 | + public static final int CODE_ACCESS_COARSE_LOCATION = 6; | |
37 | + public static final int CODE_READ_EXTERNAL_STORAGE = 7; | |
38 | + public static final int CODE_WRITE_EXTERNAL_STORAGE = 8; | |
39 | + public static final int CODE_MULTI_PERMISSION = 100; | |
40 | + | |
41 | + //com.huawei.permission.sec.PERMISSION_MDM_SDCARD | |
42 | +// public static final String PERMISSION_MDM_SDCARD = "PERMISSION_MDM_SDCARD"; | |
43 | + public static final String PERMISSION_RECORD_AUDIO = Manifest.permission.RECORD_AUDIO; | |
44 | + public static final String PERMISSION_GET_ACCOUNTS = Manifest.permission.GET_ACCOUNTS; | |
45 | + public static final String PERMISSION_READ_PHONE_STATE = Manifest.permission.READ_PHONE_STATE; | |
46 | + public static final String PERMISSION_CALL_PHONE = Manifest.permission.CALL_PHONE; | |
47 | + public static final String PERMISSION_CAMERA = Manifest.permission.CAMERA; | |
48 | + public static final String PERMISSION_ACCESS_FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION; | |
49 | + public static final String PERMISSION_ACCESS_COARSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION; | |
50 | + public static final String PERMISSION_READ_EXTERNAL_STORAGE = Manifest.permission.READ_EXTERNAL_STORAGE; | |
51 | + public static final String PERMISSION_WRITE_EXTERNAL_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE; | |
52 | + | |
53 | + private static final String[] requestPermissions = { | |
54 | + PERMISSION_RECORD_AUDIO, | |
55 | + PERMISSION_GET_ACCOUNTS, | |
56 | + PERMISSION_READ_PHONE_STATE, | |
57 | + PERMISSION_CALL_PHONE, | |
58 | + PERMISSION_CAMERA, | |
59 | + PERMISSION_ACCESS_FINE_LOCATION, | |
60 | + PERMISSION_ACCESS_COARSE_LOCATION, | |
61 | + PERMISSION_READ_EXTERNAL_STORAGE, | |
62 | + PERMISSION_WRITE_EXTERNAL_STORAGE | |
63 | +// PERMISSION_MDM_SDCARD | |
64 | + }; | |
65 | + | |
66 | + public interface PermissionGrant { | |
67 | + void onPermissionGranted(int requestCode); | |
68 | + } | |
69 | + | |
70 | + /** | |
71 | + * Requests permission. | |
72 | + * | |
73 | + * @param activity | |
74 | + * @param requestCode request code, e.g. if you need request CAMERA permission,parameters is PermissionUtils.CODE_CAMERA | |
75 | + */ | |
76 | + public static void requestPermission(final Activity activity, final int requestCode, PermissionGrant permissionGrant) { | |
77 | + if (activity == null) { | |
78 | + return; | |
79 | + } | |
80 | + | |
81 | + Log.i(TAG, "requestPermission requestCode:" + requestCode); | |
82 | + if (requestCode < 0 || requestCode >= requestPermissions.length) { | |
83 | + Log.w(TAG, "requestPermission illegal requestCode:" + requestCode); | |
84 | + return; | |
85 | + } | |
86 | + | |
87 | + final String requestPermission = requestPermissions[requestCode]; | |
88 | + | |
89 | + //如果是6.0以下的手机,ActivityCompat.checkSelfPermission()会始终等于PERMISSION_GRANTED, | |
90 | + // 但是,如果用户关闭了你申请的权限,ActivityCompat.checkSelfPermission(),会导致程序崩溃(java.lang.RuntimeException: Unknown exception code: 1 msg null), | |
91 | + // 你可以使用try{}catch(){},处理异常,也可以在这个地方,低于23就什么都不做, | |
92 | + // 个人建议try{}catch(){}单独处理,提示用户开启权限。 | |
93 | +// if (Build.VERSION.SDK_INT < 23) { | |
94 | +// return; | |
95 | +// } | |
96 | + | |
97 | + int checkSelfPermission; | |
98 | + try { | |
99 | + checkSelfPermission = ActivityCompat.checkSelfPermission(activity, requestPermission); | |
100 | + } catch (RuntimeException e) { | |
101 | +// Toast.makeText(activity, "please open this permission", Toast.LENGTH_SHORT) | |
102 | +// .show(); | |
103 | + Log.e(TAG, "RuntimeException:" + e.getMessage()); | |
104 | + return; | |
105 | + } | |
106 | + | |
107 | + if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) { | |
108 | + Log.i(TAG, "ActivityCompat.checkSelfPermission != PackageManager.PERMISSION_GRANTED"); | |
109 | + | |
110 | + | |
111 | + if (ActivityCompat.shouldShowRequestPermissionRationale(activity, requestPermission)) { | |
112 | + Log.i(TAG, "requestPermission shouldShowRequestPermissionRationale"); | |
113 | + shouldShowRationale(activity, requestCode, requestPermission); | |
114 | + | |
115 | + } else { | |
116 | + Log.d(TAG, "requestCameraPermission else"); | |
117 | + ActivityCompat.requestPermissions(activity, new String[]{requestPermission}, requestCode); | |
118 | + } | |
119 | + | |
120 | + } else { | |
121 | + Log.d(TAG, "ActivityCompat.checkSelfPermission ==== PackageManager.PERMISSION_GRANTED"); | |
122 | +// Toast.makeText(activity, "opened:" + requestPermissions[requestCode], Toast.LENGTH_SHORT).show(); | |
123 | + permissionGrant.onPermissionGranted(requestCode); | |
124 | + } | |
125 | + } | |
126 | + | |
127 | + private static void requestMultiResult(Activity activity, String[] permissions, int[] grantResults, PermissionGrant permissionGrant) { | |
128 | + | |
129 | + if (activity == null) { | |
130 | + return; | |
131 | + } | |
132 | + | |
133 | + //TODO | |
134 | + Log.d(TAG, "onRequestPermissionsResult permissions length:" + permissions.length); | |
135 | + Map<String, Integer> perms = new HashMap<>(); | |
136 | + | |
137 | + ArrayList<String> notGranted = new ArrayList<>(); | |
138 | + for (int i = 0; i < permissions.length; i++) { | |
139 | + Log.d(TAG, "permissions: [i]:" + i + ", permissions[i]" + permissions[i] + ",grantResults[i]:" + grantResults[i]); | |
140 | + perms.put(permissions[i], grantResults[i]); | |
141 | + if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { | |
142 | + notGranted.add(permissions[i]); | |
143 | + } | |
144 | + } | |
145 | + | |
146 | + if (notGranted.size() == 0) { | |
147 | +// Toast.makeText(activity, "all permission success" + notGranted, Toast.LENGTH_SHORT) | |
148 | +// .show(); | |
149 | + permissionGrant.onPermissionGranted(CODE_MULTI_PERMISSION); | |
150 | + } else { | |
151 | + openSettingActivity(activity, "those permission need granted!"); | |
152 | + } | |
153 | + | |
154 | + } | |
155 | + | |
156 | + | |
157 | + /** | |
158 | + * 一次申请多个权限 | |
159 | + */ | |
160 | + public static void requestMultiPermissions(final Activity activity, PermissionGrant grant) { | |
161 | + | |
162 | + final List<String> permissionsList = getNoGrantedPermission(activity, false); | |
163 | + final List<String> shouldRationalePermissionsList = getNoGrantedPermission(activity, true); | |
164 | + | |
165 | + //TODO checkSelfPermission | |
166 | + if (permissionsList == null || shouldRationalePermissionsList == null) { | |
167 | + return; | |
168 | + } | |
169 | + Log.d(TAG, "requestMultiPermissions permissionsList:" + permissionsList.size() + ",shouldRationalePermissionsList:" + shouldRationalePermissionsList.size()); | |
170 | + | |
171 | + if (permissionsList.size() > 0) { | |
172 | + ActivityCompat.requestPermissions(activity, permissionsList.toArray(new String[permissionsList.size()]), | |
173 | + CODE_MULTI_PERMISSION); | |
174 | + Log.d(TAG, "showMessageOKCancel requestPermissions"); | |
175 | + | |
176 | + } else if (shouldRationalePermissionsList.size() > 0) { | |
177 | + showMessageOKCancel(activity, "should open those permission", | |
178 | + new DialogInterface.OnClickListener() { | |
179 | + @Override | |
180 | + public void onClick(DialogInterface dialog, int which) { | |
181 | + ActivityCompat.requestPermissions(activity, shouldRationalePermissionsList.toArray(new String[shouldRationalePermissionsList.size()]), | |
182 | + CODE_MULTI_PERMISSION); | |
183 | + Log.d(TAG, "showMessageOKCancel requestPermissions"); | |
184 | + } | |
185 | + }); | |
186 | + } else { | |
187 | + grant.onPermissionGranted(CODE_MULTI_PERMISSION); | |
188 | + } | |
189 | + | |
190 | + } | |
191 | + | |
192 | + | |
193 | + private static void shouldShowRationale(final Activity activity, final int requestCode, final String requestPermission) { | |
194 | + //TODO | |
195 | + String[] permissionsHint = activity.getResources().getStringArray(R.array.permissions); | |
196 | + showMessageOKCancel(activity, "Rationale: " + permissionsHint[requestCode], new DialogInterface.OnClickListener() { | |
197 | + @Override | |
198 | + public void onClick(DialogInterface dialog, int which) { | |
199 | + ActivityCompat.requestPermissions(activity, | |
200 | + new String[]{requestPermission}, | |
201 | + requestCode); | |
202 | + Log.d(TAG, "showMessageOKCancel requestPermissions:" + requestPermission); | |
203 | + } | |
204 | + }); | |
205 | + } | |
206 | + | |
207 | + private static void showMessageOKCancel(final Activity context, String message, DialogInterface.OnClickListener okListener) { | |
208 | + new AlertDialog.Builder(context) | |
209 | + .setMessage(message) | |
210 | + .setPositiveButton("OK", okListener) | |
211 | + .setNegativeButton("Cancel", null) | |
212 | + .create() | |
213 | + .show(); | |
214 | + | |
215 | + } | |
216 | + | |
217 | + /** | |
218 | + * @param activity | |
219 | + * @param requestCode Need consistent with requestPermission | |
220 | + * @param permissions | |
221 | + * @param grantResults | |
222 | + */ | |
223 | + public static void requestPermissionsResult(final Activity activity, final int requestCode, @NonNull String[] permissions, | |
224 | + @NonNull int[] grantResults, PermissionGrant permissionGrant) { | |
225 | + | |
226 | + if (activity == null) { | |
227 | + return; | |
228 | + } | |
229 | + Log.d(TAG, "requestPermissionsResult requestCode:" + requestCode); | |
230 | + | |
231 | + if (requestCode == CODE_MULTI_PERMISSION) { | |
232 | + requestMultiResult(activity, permissions, grantResults, permissionGrant); | |
233 | + return; | |
234 | + } | |
235 | + | |
236 | + if (requestCode < 0 || requestCode >= requestPermissions.length) { | |
237 | + Log.w(TAG, "requestPermissionsResult illegal requestCode:" + requestCode); | |
238 | +// Toast.makeText(activity, "illegal requestCode:" + requestCode, Toast.LENGTH_SHORT).show(); | |
239 | + return; | |
240 | + } | |
241 | + | |
242 | + Log.i(TAG, "onRequestPermissionsResult requestCode:" + requestCode + ",permissions:" + permissions.toString() | |
243 | + + ",grantResults:" + grantResults.toString() + ",length:" + grantResults.length); | |
244 | + | |
245 | + if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |
246 | + Log.i(TAG, "onRequestPermissionsResult PERMISSION_GRANTED"); | |
247 | + //TODO success, do something, can use callback | |
248 | + permissionGrant.onPermissionGranted(requestCode); | |
249 | + | |
250 | + } else { | |
251 | + //TODO hint user this permission function | |
252 | + Log.i(TAG, "onRequestPermissionsResult PERMISSION NOT GRANTED"); | |
253 | + //TODO | |
254 | + String[] permissionsHint = activity.getResources().getStringArray(R.array.permissions); | |
255 | + openSettingActivity(activity, "Result" + permissionsHint[requestCode]); | |
256 | + } | |
257 | + | |
258 | + } | |
259 | + | |
260 | + private static void openSettingActivity(final Activity activity, String message) { | |
261 | + | |
262 | + showMessageOKCancel(activity, message, new DialogInterface.OnClickListener() { | |
263 | + @Override | |
264 | + public void onClick(DialogInterface dialog, int which) { | |
265 | + Intent intent = new Intent(); | |
266 | + intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); | |
267 | + Log.d(TAG, "getPackageName(): " + activity.getPackageName()); | |
268 | + Uri uri = Uri.fromParts("package", activity.getPackageName(), null); | |
269 | + intent.setData(uri); | |
270 | + activity.startActivity(intent); | |
271 | + } | |
272 | + }); | |
273 | + } | |
274 | + | |
275 | + | |
276 | + /** | |
277 | + * @param activity | |
278 | + * @param isShouldRationale true: return no granted and shouldShowRequestPermissionRationale permissions, false:return no granted and !shouldShowRequestPermissionRationale | |
279 | + * @return | |
280 | + */ | |
281 | + public static ArrayList<String> getNoGrantedPermission(Activity activity, boolean isShouldRationale) { | |
282 | + | |
283 | + ArrayList<String> permissions = new ArrayList<>(); | |
284 | + | |
285 | + for (int i = 0; i < requestPermissions.length; i++) { | |
286 | + String requestPermission = requestPermissions[i]; | |
287 | + | |
288 | + | |
289 | + //TODO checkSelfPermission | |
290 | + int checkSelfPermission = -1; | |
291 | + try { | |
292 | + checkSelfPermission = ActivityCompat.checkSelfPermission(activity, requestPermission); | |
293 | + } catch (RuntimeException e) { | |
294 | + Toast.makeText(activity, "please open those permission", Toast.LENGTH_SHORT) | |
295 | + .show(); | |
296 | + Log.e(TAG, "RuntimeException:" + e.getMessage()); | |
297 | + return null; | |
298 | + } | |
299 | + | |
300 | + if (checkSelfPermission != PackageManager.PERMISSION_GRANTED) { | |
301 | + Log.i(TAG, "getNoGrantedPermission ActivityCompat.checkSelfPermission != PackageManager.PERMISSION_GRANTED:" + requestPermission); | |
302 | + | |
303 | + if (ActivityCompat.shouldShowRequestPermissionRationale(activity, requestPermission)) { | |
304 | + Log.d(TAG, "shouldShowRequestPermissionRationale if"); | |
305 | + if (isShouldRationale) { | |
306 | + permissions.add(requestPermission); | |
307 | + } | |
308 | + | |
309 | + } else { | |
310 | + | |
311 | + if (!isShouldRationale) { | |
312 | + permissions.add(requestPermission); | |
313 | + } | |
314 | + Log.d(TAG, "shouldShowRequestPermissionRationale else"); | |
315 | + } | |
316 | + | |
317 | + } | |
318 | + } | |
319 | + | |
320 | + return permissions; | |
321 | + } | |
322 | + | |
323 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/ResourcesUtils.java
0 → 100644
... | ... | @@ -0,0 +1,83 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.content.res.ColorStateList; | |
4 | +import android.graphics.drawable.Drawable; | |
5 | +import android.view.View; | |
6 | + | |
7 | +/** | |
8 | + * Created by Horrarndoo on 2017/9/1. | |
9 | + * <p> | |
10 | + * 资源工具类-加载资源文件 | |
11 | + */ | |
12 | + | |
13 | +public class ResourcesUtils { | |
14 | + /** | |
15 | + * 获取strings.xml资源文件字符串 | |
16 | + * | |
17 | + * @param id 资源文件id | |
18 | + * @return 资源文件对应字符串 | |
19 | + */ | |
20 | + public static String getString(int id) { | |
21 | + return AppUtils.getContext().getResources().getString(id); | |
22 | + } | |
23 | + | |
24 | + /** | |
25 | + * 获取strings.xml资源文件字符串数组 | |
26 | + * | |
27 | + * @param id 资源文件id | |
28 | + * @return 资源文件对应字符串数组 | |
29 | + */ | |
30 | + public static String[] getStringArray(int id) { | |
31 | + return AppUtils.getContext().getResources().getStringArray(id); | |
32 | + } | |
33 | + | |
34 | + /** | |
35 | + * 获取drawable资源文件图片 | |
36 | + * | |
37 | + * @param id 资源文件id | |
38 | + * @return 资源文件对应图片 | |
39 | + */ | |
40 | + public static Drawable getDrawable(int id) { | |
41 | + return AppUtils.getContext().getResources().getDrawable(id); | |
42 | + } | |
43 | + | |
44 | + /** | |
45 | + * 获取colors.xml资源文件颜色 | |
46 | + * | |
47 | + * @param id 资源文件id | |
48 | + * @return 资源文件对应颜色值 | |
49 | + */ | |
50 | + public static int getColor(int id) { | |
51 | + return AppUtils.getContext().getResources().getColor(id); | |
52 | + } | |
53 | + | |
54 | + /** | |
55 | + * 获取颜色的状态选择器 | |
56 | + * | |
57 | + * @param id 资源文件id | |
58 | + * @return 资源文件对应颜色状态 | |
59 | + */ | |
60 | + public static ColorStateList getColorStateList(int id) { | |
61 | + return AppUtils.getContext().getResources().getColorStateList(id); | |
62 | + } | |
63 | + | |
64 | + /** | |
65 | + * 获取dimens资源文件中具体像素值 | |
66 | + * | |
67 | + * @param id 资源文件id | |
68 | + * @return 资源文件对应像素值 | |
69 | + */ | |
70 | + public static int getDimen(int id) { | |
71 | + return AppUtils.getContext().getResources().getDimensionPixelSize(id);// 返回具体像素值 | |
72 | + } | |
73 | + | |
74 | + /** | |
75 | + * 加载布局文件 | |
76 | + * | |
77 | + * @param id 布局文件id | |
78 | + * @return 布局view | |
79 | + */ | |
80 | + public static View inflate(int id) { | |
81 | + return View.inflate(AppUtils.getContext(), id, null); | |
82 | + } | |
83 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/ScreenUtils.java
0 → 100644
... | ... | @@ -0,0 +1,151 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | +import android.app.ActivityGroup; | |
5 | +import android.content.Context; | |
6 | +import android.graphics.Bitmap; | |
7 | +import android.graphics.Rect; | |
8 | +import android.os.Build; | |
9 | +import android.support.v7.app.AppCompatActivity; | |
10 | +import android.util.Log; | |
11 | +import android.util.TypedValue; | |
12 | +import android.view.Display; | |
13 | +import android.view.View; | |
14 | +import android.view.ViewGroup; | |
15 | +import android.view.WindowManager; | |
16 | + | |
17 | +/** | |
18 | + * Created by Horrarndoo on 2017/9/7. | |
19 | + * <p> | |
20 | + * 屏幕相关工具类 | |
21 | + */ | |
22 | + | |
23 | +public class ScreenUtils { | |
24 | + private ScreenUtils() { | |
25 | + /* cannot be instantiated */ | |
26 | + throw new UnsupportedOperationException("cannot be instantiated"); | |
27 | + } | |
28 | + | |
29 | + | |
30 | + private static int mStatusHeight = -1; | |
31 | + | |
32 | + /** | |
33 | + * 获取屏幕的宽度 | |
34 | + * | |
35 | + * @param context | |
36 | + * @return | |
37 | + */ | |
38 | + public static int getScreenWidth(Context context) { | |
39 | + WindowManager manager = (WindowManager) context | |
40 | + .getSystemService(Context.WINDOW_SERVICE); | |
41 | + Display display = manager.getDefaultDisplay(); | |
42 | + return display.getWidth(); | |
43 | + } | |
44 | + | |
45 | + /** | |
46 | + * 获取屏幕的高度 | |
47 | + * | |
48 | + * @param context | |
49 | + * @return | |
50 | + */ | |
51 | + public static int getScreenHeight(Context context) { | |
52 | + WindowManager manager = (WindowManager) context | |
53 | + .getSystemService(Context.WINDOW_SERVICE); | |
54 | + Display display = manager.getDefaultDisplay(); | |
55 | + return display.getHeight(); | |
56 | + } | |
57 | + | |
58 | + /** | |
59 | + * 获取当前屏幕截图,不包含状态栏 | |
60 | + * | |
61 | + * @param activity | |
62 | + * @return bp | |
63 | + */ | |
64 | + public static Bitmap snapShotWithoutStatusBar(Activity activity) { | |
65 | + View view = activity.getWindow().getDecorView(); | |
66 | + view.setDrawingCacheEnabled(true); | |
67 | + view.buildDrawingCache(); | |
68 | + Bitmap bmp = view.getDrawingCache(); | |
69 | + if (bmp == null) { | |
70 | + return null; | |
71 | + } | |
72 | + Rect frame = new Rect(); | |
73 | + activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); | |
74 | + int statusBarHeight = frame.top; | |
75 | + Bitmap bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, bmp.getWidth(), bmp.getHeight() | |
76 | + - statusBarHeight); | |
77 | + view.destroyDrawingCache(); | |
78 | + view.setDrawingCacheEnabled(false); | |
79 | + | |
80 | + return bp; | |
81 | + } | |
82 | + | |
83 | + /** | |
84 | + * 获取actionbar的像素高度,默认使用android官方兼容包做actionbar兼容 | |
85 | + * | |
86 | + * @return | |
87 | + */ | |
88 | + public static int getActionBarHeight(Context context) { | |
89 | + int actionBarHeight = 0; | |
90 | + if (context instanceof AppCompatActivity && ((AppCompatActivity) context) | |
91 | + .getSupportActionBar() != null) { | |
92 | + Log.d("isAppCompatActivity", "==AppCompatActivity"); | |
93 | + actionBarHeight = ((AppCompatActivity) context).getSupportActionBar().getHeight(); | |
94 | + } else if (context instanceof Activity && ((Activity) context).getActionBar() != null) { | |
95 | + Log.d("isActivity", "==Activity"); | |
96 | + actionBarHeight = ((Activity) context).getActionBar().getHeight(); | |
97 | + } else if (context instanceof ActivityGroup) { | |
98 | + Log.d("ActivityGroup", "==ActivityGroup"); | |
99 | + if (((ActivityGroup) context).getCurrentActivity() instanceof AppCompatActivity && ( | |
100 | + (AppCompatActivity) ((ActivityGroup) context).getCurrentActivity()) | |
101 | + .getSupportActionBar() != null) { | |
102 | + actionBarHeight = ((AppCompatActivity) ((ActivityGroup) context) | |
103 | + .getCurrentActivity()).getSupportActionBar().getHeight(); | |
104 | + } else if (((ActivityGroup) context).getCurrentActivity() instanceof Activity && ( | |
105 | + (Activity) ((ActivityGroup) context).getCurrentActivity()).getActionBar() != | |
106 | + null) { | |
107 | + actionBarHeight = ((Activity) ((ActivityGroup) context).getCurrentActivity()) | |
108 | + .getActionBar().getHeight(); | |
109 | + } | |
110 | + } | |
111 | + if (actionBarHeight != 0) | |
112 | + return actionBarHeight; | |
113 | + final TypedValue tv = new TypedValue(); | |
114 | + if (context.getTheme().resolveAttribute(android.support.v7.appcompat.R.attr | |
115 | + .actionBarSize, tv, true)) { | |
116 | + if (context.getTheme().resolveAttribute(android.support.v7.appcompat.R.attr | |
117 | + .actionBarSize, tv, true)) | |
118 | + actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context | |
119 | + .getResources().getDisplayMetrics()); | |
120 | + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { | |
121 | + if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) | |
122 | + actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context | |
123 | + .getResources().getDisplayMetrics()); | |
124 | + } else { | |
125 | + if (context.getTheme().resolveAttribute(android.support.v7.appcompat.R.attr | |
126 | + .actionBarSize, tv, true)) | |
127 | + actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context | |
128 | + .getResources().getDisplayMetrics()); | |
129 | + } | |
130 | + Log.d("actionBarHeight", "====" + actionBarHeight); | |
131 | + return actionBarHeight; | |
132 | + } | |
133 | + | |
134 | + | |
135 | + /** | |
136 | + * 设置view margin | |
137 | + * | |
138 | + * @param v | |
139 | + * @param l | |
140 | + * @param t | |
141 | + * @param r | |
142 | + * @param b | |
143 | + */ | |
144 | + public static void setMargins(View v, int l, int t, int r, int b) { | |
145 | + if (v.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) { | |
146 | + ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) v.getLayoutParams(); | |
147 | + p.setMargins(l, t, r, b); | |
148 | + v.requestLayout(); | |
149 | + } | |
150 | + } | |
151 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/SnackbarUtils.java
0 → 100644
... | ... | @@ -0,0 +1,189 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.graphics.Color; | |
4 | +import android.support.design.widget.Snackbar; | |
5 | +import android.view.Gravity; | |
6 | +import android.view.LayoutInflater; | |
7 | +import android.view.View; | |
8 | +import android.widget.LinearLayout; | |
9 | +import android.widget.TextView; | |
10 | + | |
11 | +import com.share.mvpsdk.R; | |
12 | + | |
13 | + | |
14 | +/** | |
15 | + * Created by Horrarndoo on 2017/8/31. | |
16 | + * <p> | |
17 | + * Snackbar工具类 | |
18 | + */ | |
19 | +public class SnackbarUtils { | |
20 | + | |
21 | + public static final int Info = 1; | |
22 | + public static final int Confirm = 2; | |
23 | + public static final int Warning = 3; | |
24 | + public static final int Alert = 4; | |
25 | + | |
26 | + | |
27 | + public static int red = 0xfff44336; | |
28 | + public static int green = 0xff4caf50; | |
29 | + public static int blue = 0xff2195f3; | |
30 | + public static int orange = 0xffffc107; | |
31 | + | |
32 | + /** | |
33 | + * 短显示Snackbar,自定义颜色 | |
34 | + * | |
35 | + * @param view | |
36 | + * @param message | |
37 | + * @param messageColor | |
38 | + * @param backgroundColor | |
39 | + * @return | |
40 | + */ | |
41 | + public static Snackbar getShort(View view, String message, int messageColor, int | |
42 | + backgroundColor) { | |
43 | + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_SHORT); | |
44 | + setSnackbarColor(snackbar, messageColor, backgroundColor); | |
45 | + return snackbar; | |
46 | + } | |
47 | + | |
48 | + /** | |
49 | + * 长显示Snackbar,自定义颜色 | |
50 | + * | |
51 | + * @param view | |
52 | + * @param message | |
53 | + * @param messageColor | |
54 | + * @param backgroundColor | |
55 | + * @return | |
56 | + */ | |
57 | + public static Snackbar getLong(View view, String message, int messageColor, int | |
58 | + backgroundColor) { | |
59 | + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_LONG); | |
60 | + setSnackbarColor(snackbar, messageColor, backgroundColor); | |
61 | + return snackbar; | |
62 | + } | |
63 | + | |
64 | + /** | |
65 | + * 自定义时常显示Snackbar,自定义颜色 | |
66 | + * | |
67 | + * @param view | |
68 | + * @param message | |
69 | + * @param messageColor | |
70 | + * @param backgroundColor | |
71 | + * @return | |
72 | + */ | |
73 | + public static Snackbar getIndefinite(View view, String message, int duration, int | |
74 | + messageColor, int backgroundColor) { | |
75 | + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_INDEFINITE).setDuration | |
76 | + (duration); | |
77 | + setSnackbarColor(snackbar, messageColor, backgroundColor); | |
78 | + return snackbar; | |
79 | + } | |
80 | + | |
81 | + /** | |
82 | + * 短显示Snackbar,可选预设类型 | |
83 | + * | |
84 | + * @param view | |
85 | + * @param message | |
86 | + * @param type | |
87 | + * @return | |
88 | + */ | |
89 | + public static Snackbar getShort(View view, String message, int type) { | |
90 | + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_SHORT); | |
91 | + switchType(snackbar, type); | |
92 | + return snackbar; | |
93 | + } | |
94 | + | |
95 | + /** | |
96 | + * 长显示Snackbar,可选预设类型 | |
97 | + * | |
98 | + * @param view | |
99 | + * @param message | |
100 | + * @param type | |
101 | + * @return | |
102 | + */ | |
103 | + public static Snackbar getLong(View view, String message, int type) { | |
104 | + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_LONG); | |
105 | + switchType(snackbar, type); | |
106 | + return snackbar; | |
107 | + } | |
108 | + | |
109 | + /** | |
110 | + * 自定义时常显示Snackbar,可选预设类型 | |
111 | + * | |
112 | + * @param view | |
113 | + * @param message | |
114 | + * @param type | |
115 | + * @return | |
116 | + */ | |
117 | + public static Snackbar getIndefinite(View view, String message, int duration, int type) { | |
118 | + Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_INDEFINITE).setDuration | |
119 | + (duration); | |
120 | + switchType(snackbar, type); | |
121 | + return snackbar; | |
122 | + } | |
123 | + | |
124 | + //选择预设类型 | |
125 | + private static void switchType(Snackbar snackbar, int type) { | |
126 | + switch (type) { | |
127 | + case Info: | |
128 | + setSnackbarColor(snackbar, blue); | |
129 | + break; | |
130 | + case Confirm: | |
131 | + setSnackbarColor(snackbar, green); | |
132 | + break; | |
133 | + case Warning: | |
134 | + setSnackbarColor(snackbar, orange); | |
135 | + break; | |
136 | + case Alert: | |
137 | + setSnackbarColor(snackbar, Color.YELLOW, red); | |
138 | + break; | |
139 | + } | |
140 | + } | |
141 | + | |
142 | + /** | |
143 | + * 设置Snackbar背景颜色 | |
144 | + * | |
145 | + * @param snackbar | |
146 | + * @param backgroundColor | |
147 | + */ | |
148 | + public static void setSnackbarColor(Snackbar snackbar, int backgroundColor) { | |
149 | + View view = snackbar.getView(); | |
150 | + if (view != null) { | |
151 | + view.setBackgroundColor(backgroundColor); | |
152 | + } | |
153 | + } | |
154 | + | |
155 | + /** | |
156 | + * 设置Snackbar文字和背景颜色 | |
157 | + * | |
158 | + * @param snackbar | |
159 | + * @param messageColor | |
160 | + * @param backgroundColor | |
161 | + */ | |
162 | + public static void setSnackbarColor(Snackbar snackbar, int messageColor, int backgroundColor) { | |
163 | + View view = snackbar.getView(); | |
164 | + if (view != null) { | |
165 | + view.setBackgroundColor(backgroundColor); | |
166 | + ((TextView) view.findViewById(R.id.snackbar_text)).setTextColor(messageColor); | |
167 | + } | |
168 | + } | |
169 | + | |
170 | + /** | |
171 | + * 向Snackbar中添加view | |
172 | + * | |
173 | + * @param snackbar | |
174 | + * @param layoutId | |
175 | + * @param index 新加布局在Snackbar中的位置 | |
176 | + */ | |
177 | + public static void addView(Snackbar snackbar, int layoutId, int index) { | |
178 | + View snackbarview = snackbar.getView(); | |
179 | + Snackbar.SnackbarLayout snackbarLayout = (Snackbar.SnackbarLayout) snackbarview; | |
180 | + | |
181 | + View add_view = LayoutInflater.from(snackbarview.getContext()).inflate(layoutId, null); | |
182 | + | |
183 | + LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams | |
184 | + .WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); | |
185 | + p.gravity = Gravity.CENTER_VERTICAL; | |
186 | + | |
187 | + snackbarLayout.addView(add_view, index, p); | |
188 | + } | |
189 | +} | |
0 | 190 | \ No newline at end of file | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/SpUtils.java
0 → 100644
... | ... | @@ -0,0 +1,212 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | + | |
4 | +import android.content.Context; | |
5 | +import android.content.SharedPreferences; | |
6 | +import android.preference.PreferenceManager; | |
7 | + | |
8 | +import com.google.gson.Gson; | |
9 | +import com.google.gson.JsonArray; | |
10 | +import com.google.gson.JsonElement; | |
11 | +import com.google.gson.JsonParser; | |
12 | + | |
13 | +import java.util.ArrayList; | |
14 | +import java.util.List; | |
15 | + | |
16 | +/** | |
17 | + * SharedPreferences工具类封装 | |
18 | + */ | |
19 | +public class SpUtils { | |
20 | + private static SharedPreferences sp; | |
21 | + private static String mPreferencesName = "share_preference_default"; | |
22 | + | |
23 | + /** | |
24 | + * 设置preferencesName | |
25 | + * | |
26 | + * @param preferencesName preferencesName | |
27 | + */ | |
28 | + private void setPreferencesName(String preferencesName) { | |
29 | + mPreferencesName = preferencesName; | |
30 | + } | |
31 | + | |
32 | + /** | |
33 | + * 写入boolean变量至sp中 | |
34 | + * | |
35 | + * @param ctx 上下文环境 | |
36 | + * @param key 存储节点名称 | |
37 | + * @param value 存储节点的值 | |
38 | + */ | |
39 | + public static void putBoolean(Context ctx, String key, boolean value) { | |
40 | + //(存储节点文件名称,读写方式) | |
41 | + if (sp == null) { | |
42 | + sp = ctx.getSharedPreferences(mPreferencesName, Context | |
43 | + .MODE_PRIVATE); | |
44 | + } | |
45 | + sp.edit().putBoolean(key, value).apply(); | |
46 | + } | |
47 | + | |
48 | + /** | |
49 | + * 读取boolean标示从sp中 | |
50 | + * | |
51 | + * @param ctx 上下文环境 | |
52 | + * @param key 存储节点名称 | |
53 | + * @param defValue 没有此节点默认值 | |
54 | + * @return 默认值或者此节点读取到的结果 | |
55 | + */ | |
56 | + public static boolean getBoolean(Context ctx, String key, boolean defValue) { | |
57 | + //(存储节点文件名称,读写方式) | |
58 | + if (sp == null) { | |
59 | + sp = ctx.getSharedPreferences(mPreferencesName, Context | |
60 | + .MODE_PRIVATE); | |
61 | + } | |
62 | + return sp.getBoolean(key, defValue); | |
63 | + } | |
64 | + | |
65 | + /** | |
66 | + * 写入String变量至sp中 | |
67 | + * | |
68 | + * @param ctx 上下文环境 | |
69 | + * @param key 存储节点名称 | |
70 | + * @param value 存储节点的值 | |
71 | + */ | |
72 | + public static void putString(Context ctx, String key, String value) { | |
73 | + //(存储节点文件名称,读写方式) | |
74 | + if (sp == null) { | |
75 | + sp = ctx.getSharedPreferences(mPreferencesName, Context | |
76 | + .MODE_PRIVATE); | |
77 | + } | |
78 | + sp.edit().putString(key, value).apply(); | |
79 | + } | |
80 | + | |
81 | + /** | |
82 | + * 读取String标示从sp中 | |
83 | + * | |
84 | + * @param ctx 上下文环境 | |
85 | + * @param key 存储节点名称 | |
86 | + * @param defValue 没有此节点默认值 | |
87 | + * @return 默认值或者此节点读取到的结果 | |
88 | + */ | |
89 | + public static String getString(Context ctx, String key, String defValue) { | |
90 | + //(存储节点文件名称,读写方式) | |
91 | + if (sp == null) { | |
92 | + sp = ctx.getSharedPreferences(mPreferencesName, Context | |
93 | + .MODE_PRIVATE); | |
94 | + } | |
95 | + return sp.getString(key, defValue); | |
96 | + } | |
97 | + | |
98 | + | |
99 | + /** | |
100 | + * 写入int变量至sp中 | |
101 | + * | |
102 | + * @param ctx 上下文环境 | |
103 | + * @param key 存储节点名称 | |
104 | + * @param value 存储节点的值 | |
105 | + */ | |
106 | + public static void putInt(Context ctx, String key, int value) { | |
107 | + //(存储节点文件名称,读写方式) | |
108 | + if (sp == null) { | |
109 | + sp = ctx.getSharedPreferences(mPreferencesName, Context | |
110 | + .MODE_PRIVATE); | |
111 | + } | |
112 | + sp.edit().putInt(key, value).apply(); | |
113 | + } | |
114 | + | |
115 | + /** | |
116 | + * 读取int标示从sp中 | |
117 | + * | |
118 | + * @param ctx 上下文环境 | |
119 | + * @param key 存储节点名称 | |
120 | + * @param defValue 没有此节点默认值 | |
121 | + * @return 默认值或者此节点读取到的结果 | |
122 | + */ | |
123 | + public static int getInt(Context ctx, String key, int defValue) { | |
124 | + //(存储节点文件名称,读写方式) | |
125 | + if (sp == null) { | |
126 | + sp = ctx.getSharedPreferences(mPreferencesName, Context | |
127 | + .MODE_PRIVATE); | |
128 | + } | |
129 | + return sp.getInt(key, defValue); | |
130 | + } | |
131 | + | |
132 | + | |
133 | + /** | |
134 | + * 从sp中移除指定节点 | |
135 | + * | |
136 | + * @param ctx 上下文环境 | |
137 | + * @param key 需要移除节点的名称 | |
138 | + */ | |
139 | + public static void remove(Context ctx, String key) { | |
140 | + if (sp == null) { | |
141 | + sp = ctx.getSharedPreferences(mPreferencesName, Context | |
142 | + .MODE_PRIVATE); | |
143 | + } | |
144 | + sp.edit().remove(key).apply(); | |
145 | + } | |
146 | + | |
147 | + /** | |
148 | + * 保存List | |
149 | + * | |
150 | + * @param key sp key值 | |
151 | + * @param datalist list | |
152 | + * @param <T> item 类型 | |
153 | + */ | |
154 | + public static <T> void setDataList(String key, List<T> datalist) { | |
155 | + if (null == datalist || datalist.size() <= 0) | |
156 | + return; | |
157 | + | |
158 | + Gson gson = new Gson(); | |
159 | + //转换成json数据,再保存 | |
160 | + String strJson = gson.toJson(datalist); | |
161 | + SpUtils.putString(AppUtils.getContext(), key, strJson); | |
162 | + } | |
163 | + | |
164 | + /** | |
165 | + * 获取List | |
166 | + * | |
167 | + * @param key sp key值 | |
168 | + * @param <T> item 类型 | |
169 | + * @return list | |
170 | + */ | |
171 | + public static <T> List<T> getDataList(String key, Class<T> cls) { | |
172 | + List<T> datalist = new ArrayList<T>(); | |
173 | + String strJson = SpUtils.getString(AppUtils.getContext(), key, null); | |
174 | + | |
175 | + if (null == strJson) { | |
176 | + return datalist; | |
177 | + } | |
178 | + | |
179 | + try { | |
180 | + Gson gson = new Gson(); | |
181 | + // datalist = gson.fromJson(strJson, new TypeToken<List<T>>(){}.getType()); | |
182 | + JsonArray array = new JsonParser().parse(strJson).getAsJsonArray(); | |
183 | + for (final JsonElement elem : array) { | |
184 | + datalist.add(gson.fromJson(elem, cls)); | |
185 | + } | |
186 | + }catch (Exception e){ | |
187 | + e.printStackTrace(); | |
188 | + } | |
189 | + | |
190 | + return datalist; | |
191 | + } | |
192 | + | |
193 | + public static int getThemeIndex(Context context) { | |
194 | + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); | |
195 | + return prefs.getInt("ThemeIndex", 5); | |
196 | + } | |
197 | + | |
198 | + public static void setThemeIndex(Context context, int index) { | |
199 | + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); | |
200 | + prefs.edit().putInt("ThemeIndex", index).apply(); | |
201 | + } | |
202 | + | |
203 | + public static boolean getNightModel(Context context) { | |
204 | + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); | |
205 | + return prefs.getBoolean("pNightMode", false); | |
206 | + } | |
207 | + | |
208 | + public static void setNightModel(Context context, boolean nightModel) { | |
209 | + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); | |
210 | + prefs.edit().putBoolean("pNightMode", nightModel).apply(); | |
211 | + } | |
212 | +} | ... | ... |
mvpsdk/src/main/java/com/share/mvpsdk/utils/StatusBarUtils.java
0 → 100644
... | ... | @@ -0,0 +1,140 @@ |
1 | +package com.share.mvpsdk.utils; | |
2 | + | |
3 | +import android.app.Activity; | |
4 | +import android.content.Context; | |
5 | +import android.graphics.Color; | |
6 | +import android.os.Build; | |
7 | +import android.support.annotation.ColorInt; | |
8 | +import android.support.v7.widget.Toolbar; | |
9 | +import android.view.View; | |
10 | +import android.view.ViewGroup; | |
11 | +import android.view.Window; | |
12 | +import android.view.WindowManager; | |
13 | + | |
14 | +import java.lang.reflect.Field; | |
15 | + | |
16 | + | |
17 | +/** | |
18 | + * Created by Horrarndoo on 2017/8/31. | |
19 | + * <p> | |
20 | + * StatusBar工具类 | |
21 | + */ | |
22 | +public class StatusBarUtils { | |
23 | + | |
24 | + private static final int DEFAULT_STATUS_BAR_ALPHA = 0; | |
25 | + | |
26 | + /** | |
27 | + * 设置状态栏颜色 | |
28 | + * | |
29 | + * @param activity 需要设置的 activity | |
30 | + * @param color 状态栏颜色值 | |
31 | + */ | |
32 | + public static void setColor(Activity activity, @ColorInt int color) { | |
33 | + setBarColor(activity, color); | |
34 | + } | |
35 | + | |
36 | + /** | |
37 | + * 设置状态栏背景色 | |
38 | + * 4.4以下不处理 | |
39 | + * 4.4使用默认沉浸式状态栏 | |
40 | + * | |
41 | + * @param color 要为状态栏设置的颜色值 | |
42 | + */ | |
43 | + public static void setBarColor(Activity activity, int color) { | |
44 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
45 | + Window win = activity.getWindow(); | |
46 | + View decorView = win.getDecorView(); | |
47 | + win.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//沉浸式状态栏(4.4-5.0透明,5.0以上半透明) | |
48 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//android5.0以上设置透明效果 | |
49 | + win.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//清除flag,为了android5.0以上也全透明效果 | |
50 | + //让应用的主体内容占用系统状态栏的空间 | |
51 | +// int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | |
52 | +// | View.SYSTEM_UI_FLAG_LAYOUT_STABLE; | |
53 | + int option = View.SYSTEM_UI_FLAG_LAYOUT_STABLE; | |
54 | + decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() | option); | |
55 | + win.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); | |
56 | + win.setStatusBarColor(color);//设置状态栏背景色 | |
57 | + } | |
58 | + } | |
59 | + } | |
60 | + | |
61 | + /** | |
62 | + * 设置状态栏全透明 | |
63 | + * | |
64 | + * @param activity 需要设置的activity | |
65 | + */ | |
66 | + public static void setTransparent(Activity activity) { | |
67 | + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { | |
68 | + return; | |
69 | + } | |
70 | + setColor(activity, Color.TRANSPARENT); | |
71 | + } | |
72 | + | |
73 | + /** | |
74 | + * 修正 Toolbar 的位置 | |
75 | + * 在 Android 4.4 版本下无法显示内容在 StatusBar 下,所以无需修正 Toolbar 的位置 | |
76 | + * | |
77 | + * @param toolbar | |
78 | + */ | |
79 | + public static void fixToolbar(Toolbar toolbar, Activity activity) { | |
80 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { | |
81 | + int statusHeight = getStatusBarHeight(activity); | |
82 | + ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); | |
83 | + layoutParams.setMargins(0, statusHeight, 0, 0); | |
84 | + } | |
85 | + } | |
86 | + | |
87 | + /** | |
88 | + * 获取系统状态栏高度 | |
89 | + * | |
90 | + * @param context | |
91 | + * @return | |
92 | + */ | |
93 | + public static int getStatusBarHeight(Context context) { | |
94 | + Class<?> c = null; | |
95 | + Object obj = null; | |
96 | + Field field = null; | |
97 | + int x = 0, statusBarHeight = 0; | |
98 | + try { | |
99 | + c = Class.forName("com.android.internal.R$dimen"); | |
100 | + obj = c.newInstance(); | |
101 | + field = c.getField("status_bar_height"); | |
102 | + x = Integer.parseInt(field.get(obj).toString()); | |
103 | + statusBarHeight = context.getResources().getDimensionPixelSize(x); | |
104 | + } catch (Exception e1) { | |
105 | + e1.printStackTrace(); | |
106 | + } | |
107 | + return statusBarHeight; | |
108 | + } | |
109 | + | |
110 | +// /** | |
111 | +// * 获取状态栏高度 | |
112 | +// * | |
113 | +// * @param context context | |
114 | +// * @return 状态栏高度 | |
115 | +// */ | |
116 | +// private static int getStatusBarHeight(Context context) { | |
117 | +// // 获得状态栏高度 | |
118 | +// int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", | |
119 | +// "android"); | |
120 | +// return context.getResources().getDimensionPixelSize(resourceId); | |
121 | +// } | |
122 | + | |
123 | + /** | |
124 | + * 计算状态栏颜色 | |
125 | + * | |
126 | + * @param color color值 | |
127 | + * @param alpha alpha值 | |
128 | + * @return 最终的状态栏颜色 | |
129 | + */ | |
130 | + private static int calculateStatusColor(@ColorInt int color, int alpha) { | |
131 | + float a = 1 - alpha / 255f; | |
132 | + int red = color >> 16 & 0xff; | |
133 | + int green = color >> 8 & 0xff; | |
134 | + int blue = color & 0xff; | |
135 | + red = (int) (red * a + 0.5); | |
136 | + green = (int) (green * a + 0.5); | |
137 | + blue = (int) (blue * a + 0.5); | |
138 | + return 0xff << 24 | red << 16 | green << 8 | blue; | |
139 | + } | |
140 | +} | ... | ... |