提交 d70b80f6 编写于 作者: 门心叼龙's avatar 门心叼龙

virtual init

上级 186f50cc
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<AndroidXmlCodeStyleSettings>
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
</AndroidXmlCodeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
......
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>
\ No newline at end of file
apply plugin: 'com.android.application'
apply plugin: 'com.didi.virtualapk.host'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion VERSION_COMPILE_SDK
buildToolsVersion VERSION_BUILD_TOOLS
defaultConfig {
applicationId "com.fly.tour"
minSdkVersion VERSION_MIN_SDK
minSdkVersion VERSION_MIN_SDK
targetSdkVersion VERSION_TARGET_SDK
versionCode 1
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
......@@ -18,6 +20,7 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
......@@ -25,6 +28,7 @@ dependencies {
implementation 'com.didi.virtualapk:core:0.9.8'
implementation project(':lib_common')
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
......
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fly.tour" >
package="com.fly.tour">
<application
android:allowBackup="true"
......@@ -11,7 +11,7 @@
android:theme="@style/AppTheme"
android:name=".MyApplication"
>
<activity android:name=".MainActivity" >
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
......
package com.fly.tour;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.MenuItem;
import android.widget.Toast;
import com.didi.virtualapk.PluginManager;
import com.fly.tour.common.base.BaseActivity;
import com.fly.tour.entity.MainChannel;
import java.io.File;
public class MainActivity extends BaseActivity {
private Fragment mNewsFragment;
private Fragment mFindFragment;
private Fragment mMeFragment;
private Fragment mCurrFragment;
@Override
public int onBindLayout() {
return R.layout.activity_main;
}
@Override
public void initView() {
loadPlugin(this,"plugin_fly_news-release.apk");
loadPlugin(this,"plugin_fly_find-release.apk");
loadPlugin(this,"plugin_fly_me-release.apk");
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
int i = menuItem.getItemId();
if (i == R.id.navigation_trip) {
switchContent(mCurrFragment, mNewsFragment, MainChannel.NEWS.name);
mCurrFragment = mNewsFragment;
return true;
} else if (i == R.id.navigation_discover) {
switchContent(mCurrFragment, mFindFragment, MainChannel.FIND.name);
mCurrFragment = mFindFragment;
return true;
} else if (i == R.id.navigation_me) {
switchContent(mCurrFragment, mMeFragment, MainChannel.ME.name);
mCurrFragment = mMeFragment;
return true;
}
return false;
}
});
if (PluginManager.getInstance(this).getLoadedPlugin("com.fly.tour.news") == null) {
Toast.makeText(this, "plugin [com.fly.tour.news] not loaded", Toast.LENGTH_SHORT).show();
return;
}
mNewsFragment = Fragment.instantiate(this,"com.fly.tour.news.fragment.MainNewsFragment");
if (PluginManager.getInstance(this).getLoadedPlugin("com.fly.tour.find") == null) {
Toast.makeText(this, "plugin [com.fly.tour.find] not loaded", Toast.LENGTH_SHORT).show();
return;
}
mFindFragment = Fragment.instantiate(this,"com.fly.tour.find.fragment.MainFindFragment");
if (PluginManager.getInstance(this).getLoadedPlugin("com.fly.tour.me") == null) {
Toast.makeText(this, "plugin [com.fly.tour.me] not loaded", Toast.LENGTH_SHORT).show();
return;
}
mMeFragment = Fragment.instantiate(this,"com.fly.tour.me.fragment.MainMeFragment");
mCurrFragment = mNewsFragment;
if (mNewsFragment != null) {
getSupportFragmentManager().beginTransaction().replace(R.id.frame_content, mNewsFragment, MainChannel.NEWS.name).commit();
}
}
@Override
public void initData() {
}
public void switchContent(Fragment from, Fragment to, String tag) {
if (from == null || to == null) {
return;
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if (!to.isAdded()) {
transaction.hide(from).add(R.id.frame_content, to, tag).commit();
} else {
transaction.hide(from).show(to).commit();
}
}
private void loadPlugin(Context base,String apkname) {
try {
PluginManager pluginManager = PluginManager.getInstance(base);
File file = new File(base.getFilesDir(), apkname);
java.io.InputStream inputStream = base.getAssets().open(apkname, 2);
java.io.FileOutputStream outputStream = new java.io.FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
outputStream.close();
inputStream.close();
pluginManager.loadPlugin(file);
Log.i(TAG, "Loaded plugin from assets: " + file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.fly.tour
import android.support.design.widget.BottomNavigationView
import android.support.v4.app.Fragment
import android.widget.Toast
import com.didi.virtualapk.PluginManager
import com.didi.virtualapk.internal.utils.PluginUtil
import com.fly.tour.common.base.BaseActivity
import com.fly.tour.entity.MainChannel
class MainActivity : BaseActivity() {
private var mNewsFragment: Fragment? = null
private var mFindFragment: Fragment? = null
private var mMeFragment: Fragment? = null
private var mCurrFragment: Fragment? = null
override fun onBindLayout(): Int {
return R.layout.activity_main
}
override fun initData() {
val navigation = findViewById<BottomNavigationView>(R.id.navigation)
navigation.setOnNavigationItemSelectedListener(BottomNavigationView.OnNavigationItemSelectedListener { menuItem ->
val i = menuItem.itemId
if (i == R.id.navigation_trip) {
switchContent(mCurrFragment, mNewsFragment, MainChannel.NEWS.name)
mCurrFragment = mNewsFragment
return@OnNavigationItemSelectedListener true
} else if (i == R.id.navigation_discover) {
switchContent(mCurrFragment, mFindFragment, MainChannel.FIND.name)
mCurrFragment = mFindFragment
return@OnNavigationItemSelectedListener true
} else if (i == R.id.navigation_me) {
switchContent(mCurrFragment, mMeFragment, MainChannel.ME.name)
mCurrFragment = mMeFragment
return@OnNavigationItemSelectedListener true
}
false
})
PluginUtil.hookActivityResources(this, "com.fly.tour.news")
PluginUtil.hookActivityResources(this, "com.fly.tour.find")
PluginUtil.hookActivityResources(this, "com.fly.tour.me")
if (PluginManager.getInstance(this).getLoadedPlugin("com.fly.tour.news") == null) {
Toast.makeText(this, "plugin [com.fly.tour.news] not loaded", Toast.LENGTH_SHORT).show()
return
}
mNewsFragment = Fragment.instantiate(this, "com.fly.tour.news.fragment.MainNewsFragment")
if (PluginManager.getInstance(this).getLoadedPlugin("com.fly.tour.find") == null) {
Toast.makeText(this, "plugin [com.fly.tour.find] not loaded", Toast.LENGTH_SHORT).show()
return
}
mFindFragment = Fragment.instantiate(this, "com.fly.tour.find.fragment.MainFindFragment")
if (PluginManager.getInstance(this).getLoadedPlugin("com.fly.tour.me") == null) {
Toast.makeText(this, "plugin [com.fly.tour.me] not loaded", Toast.LENGTH_SHORT).show()
return
}
mMeFragment = Fragment.instantiate(this, "com.fly.tour.me.fragment.MainMeFragment")
mCurrFragment = mNewsFragment
if (mNewsFragment != null) {
supportFragmentManager.beginTransaction().replace(R.id.frame_content, mNewsFragment!!, MainChannel.NEWS.name).commit()
}
}
fun switchContent(from: Fragment?, to: Fragment?, tag: String?) {
if (from == null || to == null) {
return
}
val transaction = supportFragmentManager.beginTransaction()
if (!to.isAdded) {
transaction.hide(from).add(R.id.frame_content, to, tag).commit()
} else {
transaction.hide(from).show(to).commit()
}
}
}
\ No newline at end of file
package com.fly.tour;
import android.content.Context;
import com.didi.virtualapk.PluginManager;
import com.fly.tour.common.BaseApplication;
import com.fly.tour.common.manager.NewsDBManager;
/**
* Description: <MyApplication><br>
* Author: mxdl<br>
* Date: 2018/12/27<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public class MyApplication extends BaseApplication {
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
PluginManager.getInstance(base).init();
}
@Override
public void onCreate() {
super.onCreate();
}
}
package com.fly.tour
import android.content.Context
import android.util.Log
import com.didi.virtualapk.PluginManager
import com.fly.tour.common.BaseApplication
import com.fly.tour.common.base.BaseActivity
import java.io.File
import java.io.FileOutputStream
/**
* Description: <MyApplication><br></br>
* Author: mxdl<br></br>
* Date: 2018/12/27<br></br>
* Version: V1.0.0<br></br>
* Update: <br></br>
</MyApplication> */
class MyApplication : BaseApplication() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
PluginManager.getInstance(base).init()
}
override fun onCreate() {
super.onCreate()
loadPlugin(this, "plugin_fly_news-release.apk")
loadPlugin(this, "plugin_fly_find-release.apk")
loadPlugin(this, "plugin_fly_me-release.apk")
}
private fun loadPlugin(base: Context, apkname: String) {
try {
val pluginManager = PluginManager.getInstance(base)
val file = File(base.filesDir, apkname)
val inputStream = base.assets.open(apkname, 2)
val outputStream = FileOutputStream(file)
val buf = ByteArray(1024)
var len: Int
while (inputStream.read(buf).also { len = it } > 0) {
outputStream.write(buf, 0, len)
}
outputStream.close()
inputStream.close()
pluginManager.loadPlugin(file)
Log.i(BaseActivity.TAG, "Loaded plugin from assets: $file")
} catch (e: Exception) {
e.printStackTrace()
}
}
}
\ No newline at end of file
package com.fly.tour.entity;
/**
* Description: <主频道类型><br>
* Author: mxdl<br>
* Date: 2018/12/12<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public enum MainChannel {
NEWS(0,"NEWS"), FIND(1,"FIND"),ME(2,"ME");
public int id;
public String name;
MainChannel(int id, String name){
this.id = id;
this.name = name;
}
}
package com.fly.tour.entity
/**
* Description: <主频道类型><br></br>
* Author: mxdl<br></br>
* Date: 2018/12/12<br></br>
* Version: V1.0.0<br></br>
* Update: <br></br>
</主频道类型> */
enum class MainChannel(var id: Int, var name1: String) {
NEWS(0, "NEWS"), FIND(1, "FIND"), ME(2, "ME");
}
\ No newline at end of file
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.21'
//ext.kotlin_version = '1.3.61'
//ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
......@@ -9,6 +12,7 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
classpath 'com.didi.virtualapk:gradle:0.9.8.6'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
......
......@@ -1480,59 +1480,60 @@ int layout abc_search_view 0x7f0b0019
int layout abc_select_dialog_material 0x7f0b001a
int layout abc_tooltip 0x7f0b001b
int layout activity_main 0x7f0b001c
int layout activity_root 0x7f0b001d
int layout activity_splash 0x7f0b001e
int layout button_network_err 0x7f0b001f
int layout common_toolbar 0x7f0b0020
int layout common_toolbar_leftbtn 0x7f0b0021
int layout design_bottom_navigation_item 0x7f0b0022
int layout design_bottom_sheet_dialog 0x7f0b0023
int layout design_layout_snackbar 0x7f0b0024
int layout design_layout_snackbar_include 0x7f0b0025
int layout design_layout_tab_icon 0x7f0b0026
int layout design_layout_tab_text 0x7f0b0027
int layout design_menu_item_action_area 0x7f0b0028
int layout design_navigation_item 0x7f0b0029
int layout design_navigation_item_header 0x7f0b002a
int layout design_navigation_item_separator 0x7f0b002b
int layout design_navigation_item_subheader 0x7f0b002c
int layout design_navigation_menu 0x7f0b002d
int layout design_navigation_menu_item 0x7f0b002e
int layout design_text_input_password_icon 0x7f0b002f
int layout fragment_common_dialog 0x7f0b0030
int layout fragment_photo_select 0x7f0b0031
int layout fragment_root 0x7f0b0032
int layout layout_daisy 0x7f0b0033
int layout layout_head 0x7f0b0034
int layout mis_activity_default 0x7f0b0035
int layout mis_cmp_customer_actionbar 0x7f0b0036
int layout mis_fragment_multi_image 0x7f0b0037
int layout mis_list_item_camera 0x7f0b0038
int layout mis_list_item_folder 0x7f0b0039
int layout mis_list_item_image 0x7f0b003a
int layout mtrl_layout_snackbar 0x7f0b003b
int layout mtrl_layout_snackbar_include 0x7f0b003c
int layout notification_action 0x7f0b003d
int layout notification_action_tombstone 0x7f0b003e
int layout notification_template_custom_big 0x7f0b003f
int layout notification_template_icon_group 0x7f0b0040
int layout notification_template_part_chronometer 0x7f0b0041
int layout notification_template_part_time 0x7f0b0042
int layout rotate_progress_dialog_layout 0x7f0b0043
int layout select_dialog_item_material 0x7f0b0044
int layout select_dialog_multichoice_material 0x7f0b0045
int layout select_dialog_singlechoice_material 0x7f0b0046
int layout stub_init_loading 0x7f0b0047
int layout stub_net_error 0x7f0b0048
int layout stub_no_car 0x7f0b0049
int layout stub_no_data 0x7f0b004a
int layout stub_trans_loading 0x7f0b004b
int layout support_simple_spinner_dropdown_item 0x7f0b004c
int layout view_init_loading 0x7f0b004d
int layout view_net_error 0x7f0b004e
int layout view_no_data 0x7f0b004f
int layout view_setting_bar 0x7f0b0050
int layout view_trans_loading 0x7f0b0051
int layout activity_main2 0x7f0b001d
int layout activity_root 0x7f0b001e
int layout activity_splash 0x7f0b001f
int layout button_network_err 0x7f0b0020
int layout common_toolbar 0x7f0b0021
int layout common_toolbar_leftbtn 0x7f0b0022
int layout design_bottom_navigation_item 0x7f0b0023
int layout design_bottom_sheet_dialog 0x7f0b0024
int layout design_layout_snackbar 0x7f0b0025
int layout design_layout_snackbar_include 0x7f0b0026
int layout design_layout_tab_icon 0x7f0b0027
int layout design_layout_tab_text 0x7f0b0028
int layout design_menu_item_action_area 0x7f0b0029
int layout design_navigation_item 0x7f0b002a
int layout design_navigation_item_header 0x7f0b002b
int layout design_navigation_item_separator 0x7f0b002c
int layout design_navigation_item_subheader 0x7f0b002d
int layout design_navigation_menu 0x7f0b002e
int layout design_navigation_menu_item 0x7f0b002f
int layout design_text_input_password_icon 0x7f0b0030
int layout fragment_common_dialog 0x7f0b0031
int layout fragment_photo_select 0x7f0b0032
int layout fragment_root 0x7f0b0033
int layout layout_daisy 0x7f0b0034
int layout layout_head 0x7f0b0035
int layout mis_activity_default 0x7f0b0036
int layout mis_cmp_customer_actionbar 0x7f0b0037
int layout mis_fragment_multi_image 0x7f0b0038
int layout mis_list_item_camera 0x7f0b0039
int layout mis_list_item_folder 0x7f0b003a
int layout mis_list_item_image 0x7f0b003b
int layout mtrl_layout_snackbar 0x7f0b003c
int layout mtrl_layout_snackbar_include 0x7f0b003d
int layout notification_action 0x7f0b003e
int layout notification_action_tombstone 0x7f0b003f
int layout notification_template_custom_big 0x7f0b0040
int layout notification_template_icon_group 0x7f0b0041
int layout notification_template_part_chronometer 0x7f0b0042
int layout notification_template_part_time 0x7f0b0043
int layout rotate_progress_dialog_layout 0x7f0b0044
int layout select_dialog_item_material 0x7f0b0045
int layout select_dialog_multichoice_material 0x7f0b0046
int layout select_dialog_singlechoice_material 0x7f0b0047
int layout stub_init_loading 0x7f0b0048
int layout stub_net_error 0x7f0b0049
int layout stub_no_car 0x7f0b004a
int layout stub_no_data 0x7f0b004b
int layout stub_trans_loading 0x7f0b004c
int layout support_simple_spinner_dropdown_item 0x7f0b004d
int layout view_init_loading 0x7f0b004e
int layout view_net_error 0x7f0b004f
int layout view_no_data 0x7f0b0050
int layout view_setting_bar 0x7f0b0051
int layout view_trans_loading 0x7f0b0052
int menu menu_navigation 0x7f0c0000
int menu menu_toolbar_add 0x7f0c0001
int mipmap default_ptr_rotate 0x7f0d0000
......
......@@ -5,6 +5,8 @@ android.arch.lifecycle:livedata-core:1.1.1 0
android.arch.lifecycle:livedata:1.1.1 0
android.arch.lifecycle:runtime:1.1.1 4096
android.arch.lifecycle:viewmodel:1.1.1 4096
androidx.constraintlayout:constraintlayout-solver:1.1.3 121203
androidx.constraintlayout:constraintlayout:1.1.3 0
com.android.support.constraint:constraint-layout-solver:1.1.3 120857
com.android.support.constraint:constraint-layout:1.1.3 0
com.android.support:animated-vector-drawable:28.0.0 4096
......@@ -21,6 +23,7 @@ com.android.support:drawerlayout:28.0.0 4096
com.android.support:interpolator:28.0.0 0
com.android.support:loader:28.0.0 0
com.android.support:localbroadcastmanager:28.0.0 0
com.android.support:multidex:1.0.1 0
com.android.support:print:28.0.0 4096
com.android.support:recyclerview-v7:28.0.0 4096
com.android.support:slidingpanelayout:28.0.0 0
......@@ -48,4 +51,8 @@ lib_common:debug:unspecified 0
lib_fly_db:debug:unspecified 0
lib_refresh_layout:debug:unspecified 0
org.greenrobot:eventbus:3.1.1 59043
org.jetbrains.kotlin:kotlin-stdlib-common:1.3.21 153220
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 3119
org.jetbrains.kotlin:kotlin-stdlib:1.3.21 1185426
org.jetbrains:annotations:13.0 17536
org.reactivestreams:reactive-streams:1.0.2 2097
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion VERSION_COMPILE_SDK
......@@ -11,6 +13,10 @@ android {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
// ndk {
// abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
// }
}
buildTypes {
......@@ -27,6 +33,7 @@ dependencies {
api fileTree(include: ['*.jar'], dir: 'libs')
api project(":lib_refresh_layout")
api project(':lib_fly_db')
api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
api 'com.android.support:appcompat-v7:28.0.0'
api 'com.android.support:design:28.0.0'
api 'com.android.support:recyclerview-v7:28.0.0'
......@@ -38,7 +45,7 @@ dependencies {
api 'com.google.code.gson:gson:2.6.1'
api 'com.github.tbruyelle:rxpermissions:0.10.2'
api 'com.github.lovetuzitong:MultiImageSelector:1.2'
api 'com.android.support:multidex:1.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
......
package com.fly.tour.common;
package com.fly.tour.common
import android.app.Application;
import com.fly.tour.common.util.log.KLog;
import android.app.Application
import android.support.multidex.MultiDexApplication
/**
* Description: <初始化应用程序><br>
......@@ -10,15 +9,15 @@ import com.fly.tour.common.util.log.KLog;
* Date: 2018/6/6<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public class BaseApplication extends Application {
private static BaseApplication mApplication;
@Override
public void onCreate() {
super.onCreate();
mApplication = this;
</初始化应用程序> */
open class BaseApplication : MultiDexApplication() {
override fun onCreate() {
super.onCreate()
instance = this
}
public static BaseApplication getInstance(){
return mApplication;
companion object {
var instance: BaseApplication? = null
private set
}
}
package com.fly.tour.common.base;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewStub;
import android.widget.TextView;
import com.fly.tour.common.R;
import com.fly.tour.common.event.common.BaseActivityEvent;
import com.fly.tour.common.manager.ActivityManager;
import com.fly.tour.common.mvp.BaseView;
import com.fly.tour.common.util.NetUtil;
import com.fly.tour.common.view.LoadingInitView;
import com.fly.tour.common.view.LoadingTransView;
import com.fly.tour.common.view.NetErrorView;
import com.fly.tour.common.view.NoDataView;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
/**
* Description: <BaseActivity><br>
* Author: mxdl<br>
* Date: 2018/1/16<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public abstract class BaseActivity extends RxAppCompatActivity implements BaseView {
protected static final String TAG = BaseActivity.class.getSimpleName();
protected TextView mTxtTitle;
protected Toolbar mToolbar;
protected NetErrorView mNetErrorView;
protected NoDataView mNoDataView;
protected LoadingInitView mLoadingInitView;
protected LoadingTransView mLoadingTransView;
private boolean isrefresh = false;
private ViewStub mViewStubToolbar;
private ViewStub mViewStubContent;
private ViewStub mViewStubInitLoading;
private ViewStub mViewStubTransLoading;
private ViewStub mViewStubNoData;
private ViewStub mViewStubError;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_root);
initCommonView();
initView();
initListener();
initData();
EventBus.getDefault().register(this);
ActivityManager.getInstance().addActivity(this);
}
protected void initCommonView() {
mViewStubToolbar = findViewById(R.id.view_stub_toolbar);
mViewStubContent = findViewById(R.id.view_stub_content);
mViewStubContent = findViewById(R.id.view_stub_content);
mViewStubInitLoading = findViewById(R.id.view_stub_init_loading);
mViewStubTransLoading = findViewById(R.id.view_stub_trans_loading);
mViewStubError = findViewById(R.id.view_stub_error);
mViewStubNoData = findViewById(R.id.view_stub_nodata);
if (enableToolbar()) {
mViewStubToolbar.setLayoutResource(onBindToolbarLayout());
View view = mViewStubToolbar.inflate();
initToolbar(view);
}
mViewStubContent.setLayoutResource(onBindLayout());
mViewStubContent.inflate();
}
protected void initToolbar(View view) {
mToolbar = view.findViewById(R.id.toolbar_root);
mTxtTitle = view.findViewById(R.id.toolbar_title);
if (mToolbar != null) {
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
}
}
@Override
protected void onTitleChanged(CharSequence title, int color) {
super.onTitleChanged(title, color);
if (mTxtTitle != null && !TextUtils.isEmpty(title)) {
mTxtTitle.setText(title);
}
//可以再次覆盖设置title
String tootBarTitle = getTootBarTitle();
if (mTxtTitle != null && !TextUtils.isEmpty(tootBarTitle)) {
mTxtTitle.setText(tootBarTitle);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
ActivityManager.getInstance().finishActivity(this);
}
public int onBindToolbarLayout() {
return R.layout.common_toolbar;
}
public abstract int onBindLayout();
public abstract void initView();
public abstract void initData();
public void initListener() {
}
@Override
public void finishActivity() {
finish();
}
public String getTootBarTitle() {
return "";
}
public boolean enableToolbar() {
return true;
}
public void showInitLoadView() {
showInitLoadView(true);
}
public void hideInitLoadView() {
showInitLoadView(false);
}
@Override
public void showTransLoadingView() {
showTransLoadingView(true);
}
@Override
public void hideTransLoadingView() {
showTransLoadingView(false);
}
public void showNoDataView() {
showNoDataView(true);
}
public void showNoDataView(int resid) {
showNoDataView(true, resid);
}
public void hideNoDataView() {
showNoDataView(false);
}
public void hideNetWorkErrView() {
showNetWorkErrView(false);
}
public void showNetWorkErrView() {
showNetWorkErrView(true);
}
private void showInitLoadView(boolean show) {
if (mLoadingInitView == null) {
View view = mViewStubInitLoading.inflate();
mLoadingInitView = view.findViewById(R.id.view_init_loading);
}
mLoadingInitView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoadingInitView.loading(show);
}
private void showNetWorkErrView(boolean show) {
if (mNetErrorView == null) {
View view = mViewStubError.inflate();
mNetErrorView = view.findViewById(R.id.view_net_error);
mNetErrorView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!NetUtil.checkNetToast()) {
return;
}
hideNetWorkErrView();
initData();
}
});
}
mNetErrorView.setVisibility(show ? View.VISIBLE : View.GONE);
}
private void showNoDataView(boolean show) {
if (mNoDataView == null) {
View view = mViewStubNoData.inflate();
mNoDataView = view.findViewById(R.id.view_no_data);
}
mNoDataView.setVisibility(show ? View.VISIBLE : View.GONE);
}
private void showNoDataView(boolean show, int resid) {
showNoDataView(show);
if (show) {
mNoDataView.setNoDataView(resid);
}
}
private void showTransLoadingView(boolean show) {
if (mLoadingTransView == null) {
View view = mViewStubTransLoading.inflate();
mLoadingTransView = view.findViewById(R.id.view_trans_loading);
}
mLoadingTransView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoadingTransView.loading(show);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public <T> void onEvent(BaseActivityEvent<T> event) {
}
}
package com.fly.tour.common.base
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.support.v7.widget.Toolbar
import android.text.TextUtils
import android.view.View
import android.view.ViewStub
import android.widget.TextView
import com.fly.tour.common.R
import com.fly.tour.common.event.common.BaseActivityEvent
import com.fly.tour.common.manager.ActivityManager
import com.fly.tour.common.mvp.BaseView
import com.fly.tour.common.util.NetUtil
import com.fly.tour.common.view.LoadingInitView
import com.fly.tour.common.view.LoadingTransView
import com.fly.tour.common.view.NetErrorView
import com.fly.tour.common.view.NoDataView
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
/**
* Description: <BaseActivity><br>
* Author: mxdl<br>
* Date: 2018/1/16<br>
* Version: V1.0.0<br>
* Update: <br>
</BaseActivity> */
abstract class BaseActivity : RxAppCompatActivity(), BaseView {
protected lateinit var mTxtTitle: TextView
protected lateinit var mToolbar: Toolbar
protected var mNetErrorView: NetErrorView? = null
protected var mNoDataView: NoDataView? = null
protected var mLoadingInitView: LoadingInitView? = null
protected var mLoadingTransView: LoadingTransView? = null
private lateinit var mViewStubToolbar: ViewStub
private lateinit var mViewStubContent: ViewStub
private lateinit var mViewStubInitLoading: ViewStub
private lateinit var mViewStubTransLoading: ViewStub
private lateinit var mViewStubNoData: ViewStub
private lateinit var mViewStubError: ViewStub
private val isrefresh = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
setContentView(R.layout.activity_root)
initCommonView()
initListener()
initData()
EventBus.getDefault().register(this)
ActivityManager.getInstance()?.addActivity(this)
}
protected open fun initCommonView() {
mViewStubToolbar = findViewById(R.id.view_stub_toolbar)
mViewStubContent = findViewById(R.id.view_stub_content)
mViewStubContent = findViewById(R.id.view_stub_content)
mViewStubInitLoading = findViewById(R.id.view_stub_init_loading)
mViewStubTransLoading = findViewById(R.id.view_stub_trans_loading)
mViewStubError = findViewById(R.id.view_stub_error)
mViewStubNoData = findViewById(R.id.view_stub_nodata)
if (enableToolbar()) {
mViewStubToolbar.layoutResource = onBindToolbarLayout()
val view = mViewStubToolbar.inflate()
initToolbar(view)
}
mViewStubContent.layoutResource = onBindLayout()
mViewStubContent.inflate()
}
protected fun initToolbar(view: View) {
mToolbar = view.findViewById(R.id.toolbar_root)
mTxtTitle = view.findViewById(R.id.toolbar_title)
if (mToolbar != null) {
setSupportActionBar(mToolbar)
supportActionBar!!.setDisplayShowTitleEnabled(false)
mToolbar.setNavigationOnClickListener { onBackPressed() }
}
}
override fun onTitleChanged(title: CharSequence, color: Int) {
super.onTitleChanged(title, color)
if (mTxtTitle != null && !TextUtils.isEmpty(title)) {
mTxtTitle.text = title
}
//可以再次覆盖设置title
val tootBarTitle = getTootBarTitle()
if (mTxtTitle != null && !TextUtils.isEmpty(tootBarTitle)) {
mTxtTitle.text = tootBarTitle
}
}
open fun getTootBarTitle(): String{
return ""
}
open fun onBindToolbarLayout(): Int {
return R.layout.common_toolbar
}
override fun onDestroy() {
super.onDestroy()
EventBus.getDefault().unregister(this)
ActivityManager.getInstance()?.finishActivity(this)
}
abstract fun onBindLayout(): Int
abstract override fun initData()
override fun initListener() {}
override fun finishActivity() {
finish()
}
fun enableToolbar(): Boolean {
return true
}
override fun showInitLoadView() {
showInitLoadView(true)
}
override fun hideInitLoadView() {
showInitLoadView(false)
}
override fun showTransLoadingView() {
showTransLoadingView(true)
}
override fun hideTransLoadingView() {
showTransLoadingView(false)
}
override fun showNoDataView() {
showNoDataView(true)
}
override fun showNoDataView(resid: Int) {
showNoDataView(true, resid)
}
override fun hideNoDataView() {
showNoDataView(false)
}
override fun hideNetWorkErrView() {
showNetWorkErrView(false)
}
override fun showNetWorkErrView() {
showNetWorkErrView(true)
}
private fun showInitLoadView(show: Boolean) {
if (mLoadingInitView == null) {
val view = mViewStubInitLoading.inflate()
mLoadingInitView = view.findViewById(R.id.view_init_loading)
}
mLoadingInitView?.visibility = if (show) View.VISIBLE else View.GONE
mLoadingInitView?.loading(show)
}
private fun showNetWorkErrView(show: Boolean) {
if (mNetErrorView == null) {
val view = mViewStubError.inflate()
mNetErrorView = view.findViewById(R.id.view_net_error)
mNetErrorView?.setOnClickListener(View.OnClickListener {
if (!NetUtil.checkNetToast()) {
return@OnClickListener
}
hideNetWorkErrView()
initData()
})
}
mNetErrorView?.visibility = if (show) View.VISIBLE else View.GONE
}
private fun showNoDataView(show: Boolean) {
if (mNoDataView == null) {
val view = mViewStubNoData.inflate()
mNoDataView = view.findViewById(R.id.view_no_data)
}
mNoDataView?.visibility = if (show) View.VISIBLE else View.GONE
}
private fun showNoDataView(show: Boolean, resid: Int) {
showNoDataView(show)
if (show) {
mNoDataView?.setNoDataView(resid)
}
}
private fun showTransLoadingView(show: Boolean) {
if (mLoadingTransView == null) {
val view = mViewStubTransLoading.inflate()
mLoadingTransView = view.findViewById(R.id.view_trans_loading)
}
mLoadingTransView?.visibility = if (show) View.VISIBLE else View.GONE
mLoadingTransView?.loading(show)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun <T> onEvent(event: BaseActivityEvent<T>) {
}
companion object {
public val TAG = BaseActivity::class.java.getSimpleName()
}
}
package com.fly.tour.common.base;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
/**
* Description: <BaseAdapter><br>
* Author: mxdl<br>
* Date: 2018/1/15<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public abstract class BaseAdapter<E, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
protected Context mContext;
protected List<E> mList;
protected OnItemClickListener mItemClickListener;
protected OnItemLongClickListener mOnItemLongClickListener;
public BaseAdapter(Context context) {
mContext = context;
mList = new ArrayList<E>();
}
@NonNull
@Override
public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
int layoutid = onBindLayout();
View view = LayoutInflater.from(mContext).inflate(layoutid, parent, false);
return onCreateHolder(view);
}
//绑定布局文件
protected abstract int onBindLayout();
//创建一个holder
protected abstract VH onCreateHolder(View view);
//绑定数据
protected abstract void onBindData(VH holder, E e,int positon);
@Override
public void onBindViewHolder(@NonNull VH holder, final int position) {
final E e = mList.get(position);
if (mItemClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mItemClickListener.onItemClick(e,position);
}
});
}
if (mOnItemLongClickListener != null) {
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
return mOnItemLongClickListener.onItemLongClick(e,position);
}
});
}
onBindData(holder, e,position);
}
@Override
public int getItemCount() {
return mList.size();
}
public void addAll(List<E> list) {
if (list != null && list.size() > 0) {
mList.addAll(list);
notifyDataSetChanged();
}
}
public void refresh(List<E> list){
mList.clear();
if (list != null && list.size() > 0) {
mList.addAll(list);
}
notifyDataSetChanged();
}
public void remove(int positon) {
mList.remove(positon);
notifyDataSetChanged();
}
public void remove(E e) {
mList.remove(e);
notifyDataSetChanged();
}
public void add(E e) {
mList.add(e);
notifyDataSetChanged();
}
public void addLast(E e) {
add(e);
}
public void addFirst(E e) {
mList.add(0,e);
notifyDataSetChanged();
}
public void clear() {
mList.clear();
notifyDataSetChanged();
}
public List<E> getDataList() {
return mList;
}
public void setItemClickListener(OnItemClickListener itemClickListener) {
mItemClickListener = itemClickListener;
}
public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
mOnItemLongClickListener = onItemLongClickListener;
}
public interface OnItemClickListener<E> {
void onItemClick(E e, int position);
}
public interface OnItemLongClickListener<E> {
boolean onItemLongClick(E e, int postion);
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
public List<E> getListData(){
return mList;
}
}
package com.fly.tour.common.base
import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import java.util.ArrayList
/**
* Description: <BaseAdapter><br>
* Author: mxdl<br>
* Date: 2018/1/15<br>
* Version: V1.0.0<br>
* Update: <br>
</BaseAdapter> */
abstract class BaseAdapter<E, VH : RecyclerView.ViewHolder>(protected var mContext: Context) : RecyclerView.Adapter<VH>() {
protected var mList: MutableList<E>
protected var mItemClickListener: OnItemClickListener<E>? = null
protected var mOnItemLongClickListener: OnItemLongClickListener<E>? = null
val dataList: List<E>
get() = mList
val listData: List<E>
get() = mList
init {
mList = ArrayList()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
val layoutid = onBindLayout()
val view = LayoutInflater.from(mContext).inflate(layoutid, parent, false)
return onCreateHolder(view)
}
//绑定布局文件
protected abstract fun onBindLayout(): Int
//创建一个holder
protected abstract fun onCreateHolder(view: View): VH
//绑定数据
protected abstract fun onBindData(holder: VH, e: E, positon: Int)
override fun onBindViewHolder(holder: VH, position: Int) {
val e = mList[position]
if (mItemClickListener != null) {
holder.itemView.setOnClickListener { mItemClickListener!!.onItemClick(e, position) }
}
if (mOnItemLongClickListener != null) {
holder.itemView.setOnLongClickListener { mOnItemLongClickListener!!.onItemLongClick(e, position) }
}
onBindData(holder, e, position)
}
override fun getItemCount(): Int {
return mList.size
}
fun addAll(list: List<E>?) {
if (list != null && list.size > 0) {
mList.addAll(list)
notifyDataSetChanged()
}
}
fun refresh(list: List<E>?) {
mList.clear()
if (list != null && list.size > 0) {
mList.addAll(list)
}
notifyDataSetChanged()
}
fun remove(positon: Int) {
mList.removeAt(positon)
notifyDataSetChanged()
}
fun remove(e: E) {
mList.remove(e)
notifyDataSetChanged()
}
fun add(e: E) {
mList.add(e)
notifyDataSetChanged()
}
fun addLast(e: E) {
add(e)
}
fun addFirst(e: E) {
mList.add(0, e)
notifyDataSetChanged()
}
fun clear() {
mList.clear()
notifyDataSetChanged()
}
fun setItemClickListener(itemClickListener: OnItemClickListener<E>) {
mItemClickListener = itemClickListener
}
fun setOnItemLongClickListener(onItemLongClickListener: OnItemLongClickListener<E>) {
mOnItemLongClickListener = onItemLongClickListener
}
interface OnItemClickListener<E> {
fun onItemClick(e: E, position: Int)
}
interface OnItemLongClickListener<E> {
fun onItemLongClick(e: E, postion: Int): Boolean
}
override fun getItemViewType(position: Int): Int {
return super.getItemViewType(position)
}
}
package com.fly.tour.common.base;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.TextView;
import com.fly.tour.common.R;
import com.fly.tour.common.event.common.BaseFragmentEvent;
import com.fly.tour.common.mvp.BaseView;
import com.fly.tour.common.util.NetUtil;
import com.fly.tour.common.util.log.KLog;
import com.fly.tour.common.view.LoadingInitView;
import com.fly.tour.common.view.LoadingTransView;
import com.fly.tour.common.view.NetErrorView;
import com.fly.tour.common.view.NoDataView;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
/**
* Description: <BaseFragment><br>
* Author: mxdl<br>
* Date: 2018/1/15<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public abstract class BaseFragment extends Fragment implements BaseView {
protected static final String TAG = BaseFragment.class.getSimpleName();
protected RxAppCompatActivity mActivity;
protected View mView;
protected TextView mTxtTitle;
protected Toolbar mToolbar;
protected NetErrorView mNetErrorView;
protected NoDataView mNoDataView;
protected LoadingInitView mLoadingInitView;
protected LoadingTransView mLoadingTransView;
private ViewStub mViewStubToolbar;
private ViewStub mViewStubContent;
private ViewStub mViewStubInitLoading;
private ViewStub mViewStubTransLoading;
private ViewStub mViewStubNoData;
private ViewStub mViewStubError;
private boolean isViewCreated = false;
private boolean isViewVisable = false;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = (RxAppCompatActivity) getActivity();
EventBus.getDefault().register(this);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.fragment_root, container, false);
initCommonView(mView);
initView(mView);
initListener();
return mView;
}
public void initCommonView(View view) {
mViewStubToolbar = view.findViewById(R.id.view_stub_toolbar);
mViewStubContent = view.findViewById(R.id.view_stub_content);
mViewStubContent = view.findViewById(R.id.view_stub_content);
mViewStubInitLoading = view.findViewById(R.id.view_stub_init_loading);
mViewStubTransLoading = view.findViewById(R.id.view_stub_trans_loading);
mViewStubNoData = view.findViewById(R.id.view_stub_nodata);
mViewStubError = view.findViewById(R.id.view_stub_error);
if (enableToolbar()) {
mViewStubToolbar.setLayoutResource(onBindToolbarLayout());
View viewTooBbar = mViewStubToolbar.inflate();
initTooBar(viewTooBbar);
}
mViewStubContent.setLayoutResource(onBindLayout());
mViewStubContent.inflate();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
isViewCreated = true;
//如果启用了懒加载就进行懒加载,否则就进行预加载
if (enableLazyData()) {
lazyLoad();
} else {
initData();
}
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isViewVisable = isVisibleToUser;
//如果启用了懒加载就进行懒加载,
if (enableLazyData() && isViewVisable) {
lazyLoad();
}
}
private void lazyLoad() {
//这里进行双重标记判断,必须确保onCreateView加载完毕且页面可见,才加载数据
KLog.v("MYTAG","lazyLoad start...");
KLog.v("MYTAG","isViewCreated:"+isViewCreated);
KLog.v("MYTAG","isViewVisable"+isViewVisable);
if (isViewCreated && isViewVisable) {
initData();
//数据加载完毕,恢复标记,防止重复加载
isViewCreated = false;
isViewVisable = false;
}
}
//默认不启用懒加载
public boolean enableLazyData() {
return false;
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
protected void initTooBar(View view) {
mToolbar = view.findViewById(R.id.toolbar_root);
mTxtTitle = view.findViewById(R.id.toolbar_title);
if (mToolbar != null) {
mActivity.setSupportActionBar(mToolbar);
mActivity.getSupportActionBar().setDisplayShowTitleEnabled(false);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mActivity.onBackPressed();
}
});
}
if (mTxtTitle != null) {
mTxtTitle.setText(getToolbarTitle());
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public <T> void onEvent(BaseFragmentEvent<T> event) {
}
public abstract int onBindLayout();
public abstract void initView(View view);
public void initView() {
}
public abstract void initData();
public abstract String getToolbarTitle();
public void initListener() {
}
@Override
public void finishActivity() {
mActivity.finish();
}
public boolean enableToolbar() {
return false;
}
public int onBindToolbarLayout() {
return R.layout.common_toolbar;
}
public void showInitLoadView() {
showInitLoadView(true);
}
public void hideInitLoadView() {
showInitLoadView(false);
}
@Override
public void showTransLoadingView() {
showTransLoadingView(true);
}
@Override
public void hideTransLoadingView() {
showTransLoadingView(false);
}
public void showNoDataView() {
showNoDataView(true);
}
public void showNoDataView(int resid) {
showNoDataView(true,resid);
}
public void hideNoDataView() {
showNoDataView(false);
}
public void showNetWorkErrView() {
showNetWorkErrView(true);
}
public void hideNetWorkErrView() {
showNetWorkErrView(false);
}
private void showInitLoadView(boolean show) {
if (mLoadingInitView == null) {
View view = mViewStubInitLoading.inflate();
mLoadingInitView = view.findViewById(R.id.view_init_loading);
}
mLoadingInitView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoadingInitView.loading(show);
}
private void showNetWorkErrView(boolean show) {
if (mNetErrorView == null) {
View view = mViewStubError.inflate();
mNetErrorView = view.findViewById(R.id.view_net_error);
mNetErrorView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!NetUtil.checkNetToast()) {
return;
}
hideNetWorkErrView();
initData();
}
});
}
mNetErrorView.setVisibility(show ? View.VISIBLE : View.GONE);
}
private void showNoDataView(boolean show) {
if (mNoDataView == null) {
View view = mViewStubNoData.inflate();
mNoDataView = view.findViewById(R.id.view_no_data);
}
mNoDataView.setVisibility(show ? View.VISIBLE : View.GONE);
}
private void showNoDataView(boolean show,int resid) {
showNoDataView(show);
if(show){
mNoDataView.setNoDataView(resid);
}
}
private void showTransLoadingView(boolean show) {
if (mLoadingTransView == null) {
View view = mViewStubTransLoading.inflate();
mLoadingTransView = view.findViewById(R.id.view_trans_loading);
}
mLoadingTransView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoadingTransView.loading(show);
}
}
package com.fly.tour.common.base
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v7.widget.Toolbar
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewStub
import android.widget.TextView
import com.fly.tour.common.R
import com.fly.tour.common.event.common.BaseFragmentEvent
import com.fly.tour.common.mvp.BaseView
import com.fly.tour.common.util.NetUtil
import com.fly.tour.common.util.log.KLog
import com.fly.tour.common.view.LoadingInitView
import com.fly.tour.common.view.LoadingTransView
import com.fly.tour.common.view.NetErrorView
import com.fly.tour.common.view.NoDataView
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
/**
* Description: <BaseFragment><br>
* Author: mxdl<br>
* Date: 2018/1/15<br>
* Version: V1.0.0<br>
* Update: <br>
</BaseFragment> */
abstract class BaseFragment : Fragment(), BaseView {
protected lateinit var mActivity: RxAppCompatActivity
protected lateinit var mView: View
protected lateinit var mTxtTitle: TextView
protected lateinit var mToolbar: Toolbar
protected var mNetErrorView: NetErrorView? = null
protected var mNoDataView: NoDataView? = null
protected var mLoadingInitView: LoadingInitView? = null
protected var mLoadingTransView: LoadingTransView? = null
private lateinit var mViewStubToolbar: ViewStub
private lateinit var mViewStubContent: ViewStub
private lateinit var mViewStubInitLoading: ViewStub
private lateinit var mViewStubTransLoading: ViewStub
private lateinit var mViewStubNoData: ViewStub
private lateinit var mViewStubError: ViewStub
private var isViewCreated = false
private var isViewVisable = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mActivity = (activity as RxAppCompatActivity?)!!
EventBus.getDefault().register(this)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mView = inflater.inflate(R.layout.fragment_root, container, false)
initCommonView(mView)
return mView
}
open fun initCommonView(view: View) {
mViewStubToolbar = view.findViewById(R.id.view_stub_toolbar)
mViewStubContent = view.findViewById(R.id.view_stub_content)
mViewStubContent = view.findViewById(R.id.view_stub_content)
mViewStubInitLoading = view.findViewById(R.id.view_stub_init_loading)
mViewStubTransLoading = view.findViewById(R.id.view_stub_trans_loading)
mViewStubNoData = view.findViewById(R.id.view_stub_nodata)
mViewStubError = view.findViewById(R.id.view_stub_error)
if (enableToolbar()) {
mViewStubToolbar.layoutResource = onBindToolbarLayout()
val viewTooBbar = mViewStubToolbar.inflate()
initTooBar(viewTooBbar)
}
mViewStubContent.layoutResource = onBindLayout()
mViewStubContent.inflate()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//initView(mView)
initListener()
isViewCreated = true
//如果启用了懒加载就进行懒加载,否则就进行预加载
if (enableLazyData()) {
lazyLoad()
} else {
initData()
}
}
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
super.setUserVisibleHint(isVisibleToUser)
isViewVisable = isVisibleToUser
//如果启用了懒加载就进行懒加载,
if (enableLazyData() && isViewVisable) {
lazyLoad()
}
}
private fun lazyLoad() {
//这里进行双重标记判断,必须确保onCreateView加载完毕且页面可见,才加载数据
KLog.v("MYTAG", "lazyLoad start...")
KLog.v("MYTAG", "isViewCreated:$isViewCreated")
KLog.v("MYTAG", "isViewVisable$isViewVisable")
if (isViewCreated && isViewVisable) {
initData()
//数据加载完毕,恢复标记,防止重复加载
isViewCreated = false
isViewVisable = false
}
}
//默认不启用懒加载
open fun enableLazyData(): Boolean {
return false
}
override fun onDestroy() {
super.onDestroy()
EventBus.getDefault().unregister(this)
}
protected fun initTooBar(view: View) {
mToolbar = view.findViewById(R.id.toolbar_root)
mTxtTitle = view.findViewById(R.id.toolbar_title)
if (mToolbar != null) {
mActivity.setSupportActionBar(mToolbar)
mActivity.supportActionBar?.setDisplayShowTitleEnabled(false)
mToolbar.setNavigationOnClickListener { mActivity.onBackPressed() }
}
if (mTxtTitle != null) {
mTxtTitle.text = getTootBarTitle()
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun <T> onEvent(event: BaseFragmentEvent<T>) {
}
open fun getTootBarTitle(): String{
return ""
}
abstract fun onBindLayout(): Int
abstract override fun initData()
override fun initListener() {}
override fun finishActivity() {
mActivity.finish()
}
fun enableToolbar(): Boolean {
return false
}
open fun onBindToolbarLayout(): Int {
return R.layout.common_toolbar
}
override fun showInitLoadView() {
showInitLoadView(true)
}
override fun hideInitLoadView() {
showInitLoadView(false)
}
override fun showTransLoadingView() {
showTransLoadingView(true)
}
override fun hideTransLoadingView() {
showTransLoadingView(false)
}
override fun showNoDataView() {
showNoDataView(true)
}
override fun showNoDataView(resid: Int) {
showNoDataView(true, resid)
}
override fun hideNoDataView() {
showNoDataView(false)
}
override fun showNetWorkErrView() {
showNetWorkErrView(true)
}
override fun hideNetWorkErrView() {
showNetWorkErrView(false)
}
private fun showInitLoadView(show: Boolean) {
if (mLoadingInitView == null) {
val view = mViewStubInitLoading.inflate()
mLoadingInitView = view.findViewById(R.id.view_init_loading)
}
mLoadingInitView?.visibility = if (show) View.VISIBLE else View.GONE
mLoadingInitView?.loading(show)
}
private fun showNetWorkErrView(show: Boolean) {
if (mNetErrorView == null) {
val view = mViewStubError.inflate()
mNetErrorView = view.findViewById(R.id.view_net_error)
mNetErrorView?.setOnClickListener(View.OnClickListener {
if (!NetUtil.checkNetToast()) {
return@OnClickListener
}
hideNetWorkErrView()
initData()
})
}
mNetErrorView?.visibility = if (show) View.VISIBLE else View.GONE
}
private fun showNoDataView(show: Boolean) {
if (mNoDataView == null) {
val view = mViewStubNoData.inflate()
mNoDataView = view.findViewById(R.id.view_no_data)
}
mNoDataView?.visibility = if (show) View.VISIBLE else View.GONE
}
private fun showNoDataView(show: Boolean, resid: Int) {
showNoDataView(show)
if (show) {
mNoDataView?.setNoDataView(resid)
}
}
private fun showTransLoadingView(show: Boolean) {
if (mLoadingTransView == null) {
val view = mViewStubTransLoading.inflate()
mLoadingTransView = view.findViewById(R.id.view_trans_loading)
}
mLoadingTransView?.visibility = if (show) View.VISIBLE else View.GONE
mLoadingTransView?.loading(show)
}
companion object {
protected val TAG = BaseFragment::class.java.getSimpleName()
}
}
package com.fly.tour.common.base;
import android.os.Bundle;
import android.support.annotation.Nullable;
import com.fly.tour.common.mvp.BaseModel;
import com.fly.tour.common.mvp.BasePresenter;
/**
* Description: <BaseMvpActivity><br>
* Author: mxdl<br>
* Date: 2018/1/16<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public abstract class BaseMvpActivity<M extends BaseModel,V,P extends BasePresenter<M,V>> extends BaseActivity {
protected P mPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
mPresenter = initPresenter();
if(mPresenter != null){
mPresenter.attach((V) this);
mPresenter.injectLifecycle(this);
}
super.onCreate(savedInstanceState);
}
public abstract P initPresenter();
@Override
protected void onDestroy() {
super.onDestroy();
if(mPresenter != null){
mPresenter.detach();
}
}
}
package com.fly.tour.common.base
import android.os.Bundle
import com.fly.tour.common.mvp.BaseModel
import com.fly.tour.common.mvp.BasePresenter
/**
* Description: <BaseMvpActivity><br>
* Author: mxdl<br>
* Date: 2018/1/16<br>
* Version: V1.0.0<br>
* Update: <br>
*/
abstract class BaseMvpActivity<M : BaseModel, V, P : BasePresenter<M, V>> : BaseActivity() {
protected var mPresenter: P? = null
override fun onCreate(savedInstanceState: Bundle?) {
mPresenter = initPresenter()
mPresenter?.attach(this as V)
mPresenter?.injectLifecycle(this)
super.onCreate(savedInstanceState)
}
abstract fun initPresenter(): P
override fun onDestroy() {
super.onDestroy()
mPresenter?.detach()
}
}
package com.fly.tour.common.base;
import android.os.Bundle;
import android.support.annotation.Nullable;
import com.fly.tour.common.mvp.BaseModel;
import com.fly.tour.common.mvp.BasePresenter;
/**
* Description: <BaseMvpFragment><br>
* Author: mxdl<br>
* Date: 2018/1/15<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public abstract class BaseMvpFragment<M extends BaseModel,V,P extends BasePresenter<M,V>> extends BaseFragment {
protected P mPresenter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPresenter = initPresenter();
if(mPresenter != null){
mPresenter.attach((V) this);
mPresenter.injectLifecycle(mActivity);
}
}
@Override
public void onDestroy() {
if(mPresenter != null){
mPresenter.detach();
}
super.onDestroy();
}
public abstract P initPresenter();
}
package com.fly.tour.common.base
import android.os.Bundle
import com.fly.tour.common.mvp.BaseModel
import com.fly.tour.common.mvp.BasePresenter
/**
* Description: <BaseMvpFragment><br>
* Author: mxdl<br>
* Date: 2018/1/15<br>
* Version: V1.0.0<br>
* Update: <br>
</BaseMvpFragment> */
abstract class BaseMvpFragment<M : BaseModel, V, P : BasePresenter<M, V>> : BaseFragment() {
protected var mPresenter: P? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mPresenter = initPresenter()
mPresenter?.attach(this as V)
mPresenter?.injectLifecycle(mActivity)
}
override fun onDestroy() {
mPresenter?.detach()
super.onDestroy()
}
abstract fun initPresenter(): P
}
package com.fly.tour.common.base;
import com.fly.tour.common.mvp.BaseModel;
import com.fly.tour.common.mvp.BaseRefreshPresenter;
import com.fly.tour.common.mvp.BaseRefreshView;
import com.refresh.lib.BaseRefreshLayout;
import com.refresh.lib.DaisyRefreshLayout;
/**
* Description: <下拉刷新、上拉加载更多的Activity><br>
* Author: mxdl<br>
* Date: 2018/2/26<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public abstract class BaseRefreshActivity<M extends BaseModel, V extends BaseRefreshView<T>, P extends BaseRefreshPresenter<M, V, T>, T> extends BaseMvpActivity<M, V, P> implements BaseRefreshView<T> {
protected DaisyRefreshLayout mRefreshLayout;
@Override
protected void initCommonView() {
super.initCommonView();
initRefreshView();
}
public void initRefreshView() {
mRefreshLayout = findViewById(onBindRreshLayout());
// 下拉刷新
mRefreshLayout.setOnRefreshListener(new BaseRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
onRefreshEvent();
}
});
// 上拉加载
mRefreshLayout.setOnLoadMoreListener(new BaseRefreshLayout.OnLoadMoreListener() {
@Override
public void onLoadMore() {
onLoadMoreEvent();
}
});
// 自动加载
mRefreshLayout.setOnAutoLoadListener(new BaseRefreshLayout.OnAutoLoadListener() {
@Override
public void onAutoLoad() {
onAutoLoadEvent();
}
});
}
protected abstract int onBindRreshLayout();
@Override
public void enableRefresh(boolean b) {
mRefreshLayout.setEnableRefresh(b);
}
@Override
public void enableLoadMore(boolean b) {
mRefreshLayout.setEnableLoadMore(b);
}
@Override
public void stopRefresh() {
mRefreshLayout.setRefreshing(false);
}
@Override
public void stopLoadMore() {
mRefreshLayout.setLoadMore(false);
}
@Override
public void autoLoadData() {
mRefreshLayout.autoRefresh();
}
}
package com.fly.tour.common.base
import android.os.Build
import android.support.annotation.RequiresApi
import com.fly.tour.common.mvp.BaseModel
import com.fly.tour.common.mvp.BaseRefreshPresenter
import com.fly.tour.common.mvp.BaseRefreshView
import com.refresh.lib.BaseRefreshLayout
import com.refresh.lib.DaisyRefreshLayout
/**
* Description: <下拉刷新></下拉刷新>、上拉加载更多的Activity><br>
* Author: mxdl<br>
* Date: 2018/2/26<br>
* Version: V1.0.0<br>
* Update: <br>
*/
abstract class BaseRefreshActivity<M : BaseModel, V : BaseRefreshView<T>, P : BaseRefreshPresenter<M, V, T>, T> : BaseMvpActivity<M, V, P>(), BaseRefreshView<T> {
protected lateinit var mRefreshLayout: DaisyRefreshLayout
override fun initCommonView() {
super.initCommonView()
initRefreshView()
}
fun initRefreshView() {
mRefreshLayout = findViewById(onBindRreshLayout())
// 下拉刷新
mRefreshLayout?.setOnRefreshListener(object : BaseRefreshLayout.OnRefreshListener {
override fun onRefresh() {
onRefreshEvent()
}
})
// 上拉加载
mRefreshLayout?.setOnLoadMoreListener(object : BaseRefreshLayout.OnLoadMoreListener {
override fun onLoadMore() {
onLoadMoreEvent()
}
})
// 自动加载
mRefreshLayout?.setOnAutoLoadListener(object : BaseRefreshLayout.OnAutoLoadListener {
override fun onAutoLoad() {
onAutoLoadEvent()
}
})
}
protected abstract fun onBindRreshLayout(): Int
override fun enableRefresh(b: Boolean) {
mRefreshLayout?.setEnableRefresh(b)
}
override fun enableLoadMore(b: Boolean) {
mRefreshLayout?.setEnableLoadMore(b)
}
override fun stopRefresh() {
mRefreshLayout?.isRefreshing = false
}
@RequiresApi(Build.VERSION_CODES.KITKAT)
override fun stopLoadMore() {
mRefreshLayout?.setLoadMore(false)
}
override fun autoLoadData() {
mRefreshLayout?.autoRefresh()
}
}
package com.fly.tour.common.base;
import android.view.View;
import com.fly.tour.common.mvp.BaseModel;
import com.fly.tour.common.mvp.BaseRefreshPresenter;
import com.fly.tour.common.mvp.BaseRefreshView;
import com.fly.tour.common.util.log.KLog;
import com.refresh.lib.BaseRefreshLayout;
import com.refresh.lib.DaisyRefreshLayout;
/**
* Description: <下拉刷新、上拉加载更多的Fragment><br>
* Author: mxdl<br>
* Date: 2018/2/25<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public abstract class BaseRefreshFragment<M extends BaseModel,V extends BaseRefreshView<T>,P extends BaseRefreshPresenter<M,V,T>,T> extends BaseMvpFragment<M,V,P> implements BaseRefreshView<T> {
protected DaisyRefreshLayout mRefreshLayout;
@Override
public void initCommonView(View view) {
super.initCommonView(view);
initRefreshView(view);
}
public void initRefreshView(View view) {
mRefreshLayout = view.findViewById(onBindRreshLayout());
mRefreshLayout.setOnRefreshListener(new BaseRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
onRefreshEvent();
}
});
mRefreshLayout.setOnLoadMoreListener(new BaseRefreshLayout.OnLoadMoreListener() {
@Override
public void onLoadMore() {
onLoadMoreEvent();
}
});
mRefreshLayout.setOnAutoLoadListener(new BaseRefreshLayout.OnAutoLoadListener() {
@Override
public void onAutoLoad() {
onAutoLoadEvent();
}
});
}
protected abstract int onBindRreshLayout();
@Override
public void enableRefresh(boolean b) {
mRefreshLayout.setEnableRefresh(b);
}
@Override
public void enableLoadMore(boolean b) {
mRefreshLayout.setEnableLoadMore(b);
}
@Override
public void stopRefresh() {
mRefreshLayout.setRefreshing(false);
}
@Override
public void stopLoadMore() {
mRefreshLayout.setLoadMore(false);
}
@Override
public void autoLoadData() {
KLog.v("MYTAG","autoLoadData start...");
if(mRefreshLayout != null){
KLog.v("MYTAG","autoLoadData1 start...");
mRefreshLayout.autoRefresh();
}
}
}
package com.fly.tour.common.base
import android.os.Build
import android.support.annotation.RequiresApi
import android.view.View
import com.fly.tour.common.mvp.BaseModel
import com.fly.tour.common.mvp.BaseRefreshPresenter
import com.fly.tour.common.mvp.BaseRefreshView
import com.fly.tour.common.util.log.KLog
import com.refresh.lib.BaseRefreshLayout
import com.refresh.lib.DaisyRefreshLayout
/**
* Description: <下拉刷新></下拉刷新>、上拉加载更多的Fragment><br>
* Author: mxdl<br>
* Date: 2018/2/25<br>
* Version: V1.0.0<br>
* Update: <br>
*/
abstract class BaseRefreshFragment<M : BaseModel, V : BaseRefreshView<T>, P : BaseRefreshPresenter<M, V, T>, T> :
BaseMvpFragment<M, V, P>(), BaseRefreshView<T> {
protected var mRefreshLayout: DaisyRefreshLayout? = null
override fun initCommonView(view: View) {
super.initCommonView(view)
initRefreshView(view)
}
fun initRefreshView(view: View) {
mRefreshLayout = view.findViewById(onBindRreshLayout())
mRefreshLayout?.setOnRefreshListener(object : BaseRefreshLayout.OnRefreshListener {
override fun onRefresh() {
onRefreshEvent()
}
})
mRefreshLayout?.setOnLoadMoreListener(object : BaseRefreshLayout.OnLoadMoreListener {
override fun onLoadMore() {
onLoadMoreEvent()
}
})
mRefreshLayout?.setOnAutoLoadListener(object : BaseRefreshLayout.OnAutoLoadListener {
override fun onAutoLoad() {
onAutoLoadEvent()
}
})
}
protected abstract fun onBindRreshLayout(): Int
override fun enableRefresh(b: Boolean) {
mRefreshLayout?.setEnableRefresh(b)
}
override fun enableLoadMore(b: Boolean) {
mRefreshLayout?.setEnableLoadMore(b)
}
override fun stopRefresh() {
mRefreshLayout?.isRefreshing = false
}
@RequiresApi(Build.VERSION_CODES.KITKAT)
override fun stopLoadMore() {
mRefreshLayout?.setLoadMore(false)
}
override fun autoLoadData() {
KLog.v("MYTAG", "autoLoadData1 start...")
mRefreshLayout?.autoRefresh()
}
}
package com.fly.tour.common.event;
/**
* Description: <BaseEvent><br>
* Author: mxdl<br>
* Date: 2018/4/4<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public class BaseEvent<T> {
private int code;
private T data;
public BaseEvent(int code) {
this.code = code;
}
public BaseEvent(int code, T data) {
this.code = code;
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
package com.fly.tour.common.event
/**
* Description: <BaseEvent><br>
* Author: mxdl<br>
* Date: 2018/4/4<br>
* Version: V1.0.0<br>
* Update: <br>
</BaseEvent> */
open class BaseEvent<T> {
var code: Int = 0
var data: T? = null
constructor(code: Int) {
this.code = code
}
constructor(code: Int, data: T) {
this.code = code
this.data = data
}
}
package com.fly.tour.common.event;
/**
* Description: <EventCode><br>
* Author: mxdl<br>
* Date: 2018/4/4<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public interface EventCode {
interface MainCode {
//1000开始
}
interface NewsCode {
//2000开始
}
interface FindCode {
//3000开始
}
interface MeCode {
//4000开始
int NEWS_TYPE_ADD = 4000;
int NEWS_TYPE_DELETE = 4001;
int NEWS_TYPE_UPDATE = 4002;
int NEWS_TYPE_QUERY = 4003;
int news_detail_add = 4004;
}
}
package com.fly.tour.common.event
/**
* Description: <EventCode><br>
* Author: mxdl<br>
* Date: 2018/4/4<br>
* Version: V1.0.0<br>
* Update: <br>
</EventCode> */
interface EventCode {
interface MainCode//1000开始
interface NewsCode//2000开始
interface FindCode//3000开始
interface MeCode {
companion object {
//4000开始
val NEWS_TYPE_ADD = 4000
val NEWS_TYPE_DELETE = 4001
val NEWS_TYPE_UPDATE = 4002
val NEWS_TYPE_QUERY = 4003
val news_detail_add = 4004
}
}
}
package com.fly.tour.common.event;
package com.fly.tour.common.event
/**
* Description: <RequestCode><br>
......@@ -6,19 +6,18 @@ package com.fly.tour.common.event;
* Date: 2019/5/27<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public interface KeyCode {
interface Main {
}
</RequestCode> */
interface KeyCode {
interface Main
interface News {
String NEWS_TYPE = "newstype";
String NEWS_ID = "newsid";
companion object {
val NEWS_TYPE = "newstype"
val NEWS_ID = "newsid"
}
}
interface Find {
}
interface Find
interface Me {
}
interface Me
}
package com.fly.tour.common.event;
package com.fly.tour.common.event
/**
* Description: <RequestCode><br>
......@@ -6,22 +6,18 @@ package com.fly.tour.common.event;
* Date: 2019/5/27<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public interface RequestCode {
interface Main {
//1000开始
}
</RequestCode> */
interface RequestCode {
interface Main//1000开始
interface News {
//2000开始
}
interface News//2000开始
interface Find {
//3000开始
}
interface Find//3000开始
interface Me {
//4000开始
int NEWS_TYPE_ADD = 4000;
companion object {
//4000开始
val NEWS_TYPE_ADD = 4000
}
}
}
package com.fly.tour.common.event.common;
package com.fly.tour.common.event.common
import com.fly.tour.common.event.BaseEvent;
import com.fly.tour.common.event.BaseEvent
/**
* Description: <BaseActivityEvent><br>
......@@ -8,9 +8,5 @@ import com.fly.tour.common.event.BaseEvent;
* Date: 2018/4/4<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public class BaseActivityEvent<T> extends BaseEvent<T> {
public BaseActivityEvent(int code) {
super(code);
}
}
</BaseActivityEvent> */
class BaseActivityEvent<T>(code: Int) : BaseEvent<T>(code)
package com.fly.tour.common.event.common;
import com.fly.tour.common.event.BaseEvent;
package com.fly.tour.common.event.common
import com.fly.tour.common.event.BaseEvent
/**
* Description: <BaseFragmentEvent><br>
......@@ -7,9 +8,5 @@ import com.fly.tour.common.event.BaseEvent;
* Date: 2018/4/4<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public class BaseFragmentEvent<T> extends BaseEvent<T> {
public BaseFragmentEvent(int code) {
super(code);
}
}
</BaseFragmentEvent> */
class BaseFragmentEvent<T>(code: Int) : BaseEvent<T>(code)
package com.fly.tour.common.event.me;
package com.fly.tour.common.event.me
import com.fly.tour.common.event.BaseEvent;
import com.fly.tour.common.event.BaseEvent
/**
* Description: <NewsDetailCurdEvent><br>
......@@ -8,9 +8,5 @@ import com.fly.tour.common.event.BaseEvent;
* Date: 2019/5/29<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public class NewsDetailCurdEvent extends BaseEvent {
public NewsDetailCurdEvent(int code) {
super(code);
}
}
</NewsDetailCurdEvent> */
class NewsDetailCurdEvent<T>(code: Int) : BaseEvent<T>(code)
package com.fly.tour.common.event.me;
package com.fly.tour.common.event.me
import com.fly.tour.common.event.BaseEvent;
import com.fly.tour.common.event.BaseEvent
/**
* Description: <NewsTypeCrudEvent><br>
......@@ -8,9 +8,5 @@ import com.fly.tour.common.event.BaseEvent;
* Date: 2019/5/29<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public class NewsTypeCrudEvent extends BaseEvent {
public NewsTypeCrudEvent(int code) {
super(code);
}
}
</NewsTypeCrudEvent> */
class NewsTypeCrudEvent<T>(code: Int) : BaseEvent<T>(code)
package com.fly.tour.common.manager;
package com.fly.tour.common.manager
import android.app.Activity;
import android.content.Context;
import android.app.Activity
import android.content.Context
import com.fly.tour.common.manager.ActivityManager.Companion.activityStack
import java.util.Stack;
import java.util.Stack
/**
* Description: <ActivityManager><br>
......@@ -11,103 +12,79 @@ import java.util.Stack;
* Date: 2018/3/18<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public class ActivityManager {
private static Stack<Activity> activityStack;
private volatile static ActivityManager instance;
</ActivityManager> */
class ActivityManager private constructor() {
private ActivityManager() {
}
public static ActivityManager getInstance() {
if (instance == null) {
synchronized (ActivityManager.class) {
if (instance == null) {
instance = new ActivityManager();
instance.activityStack = new Stack();
}
}
}
return instance;
}
val isActivityStackEmpty: Boolean
get() = activityStack.empty()
/**
* 添加Activity到堆栈
*/
public void addActivity(Activity activity) {
fun addActivity(activity: Activity) {
if (activityStack == null) {
activityStack = new Stack<Activity>();
activityStack = Stack()
}
activityStack.add(activity);
activityStack.add(activity)
}
/**
* 获取当前Activity(堆栈中最后一个压入的)
*/
public Activity currentActivity() {
fun currentActivity(): Activity? {
try {
Activity activity = activityStack.lastElement();
return activity;
} catch (Exception e) {
return null;
return activityStack.lastElement()
} catch (e: Exception) {
return null
}
}
/**
* 获取当前Activity的前一个Activity
*/
public Activity preActivity() {
int index = activityStack.size() - 2;
if (index < 0) {
return null;
}
Activity activity = activityStack.get(index);
return activity;
fun preActivity(): Activity? {
val index = activityStack.size - 2
return if (index < 0) {
null
} else activityStack[index]
}
/**
* 结束当前Activity(堆栈中最后一个压入的)
*/
public void finishActivity() {
Activity activity = activityStack.lastElement();
finishActivity(activity);
fun finishActivity() {
val activity = activityStack.lastElement()
finishActivity(activity)
}
/**
* 结束指定的Activity
*/
public void finishActivity(Activity activity) {
if (activity != null) {
activityStack.remove(activity);
activity.finish();
activity = null;
}
fun finishActivity(activity: Activity?) {
activityStack.remove(activity)
activity?.finish()
}
/**
* 移除指定的Activity
*/
public void removeActivity(Activity activity) {
if (activity != null) {
activityStack.remove(activity);
activity = null;
}
fun removeActivity(activity: Activity?) {
activityStack.remove(activity)
}
/**
* 结束指定类名的Activity
*/
public void finishActivity(Class<?> cls) {
fun finishActivity(cls: Class<*>) {
try {
for (Activity activity : activityStack) {
if (activity.getClass().equals(cls)) {
finishActivity(activity);
for (activity in activityStack) {
if (activity.javaClass == cls) {
finishActivity(activity)
}
}
} catch (Exception e) {
e.printStackTrace();
} catch (e: Exception) {
e.printStackTrace()
}
}
......@@ -115,13 +92,16 @@ public class ActivityManager {
/**
* 结束所有Activity
*/
public void finishAllActivity() {
for (int i = 0, size = activityStack.size(); i < size; i++) {
if (null != activityStack.get(i)) {
activityStack.get(i).finish();
fun finishAllActivity() {
var i = 0
val size = activityStack.size
while (i < size) {
if (null != activityStack[i]) {
activityStack[i].finish()
}
i++
}
activityStack.clear();
activityStack.clear()
}
/**
......@@ -129,12 +109,13 @@ public class ActivityManager {
*
* @param cls
*/
public void returnToActivity(Class<?> cls) {
while (activityStack.size() != 0) if (activityStack.peek().getClass() == cls) {
break;
} else {
finishActivity(activityStack.peek());
}
fun returnToActivity(cls: Class<*>) {
while (activityStack.size != 0)
if (activityStack.peek().javaClass == cls) {
break
} else {
finishActivity(activityStack.peek())
}
}
......@@ -143,15 +124,18 @@ public class ActivityManager {
* @param cls
* @return
*/
public boolean isOpenActivity(Class<?> cls) {
fun isOpenActivity(cls: Class<*>): Boolean {
if (activityStack != null) {
for (int i = 0, size = activityStack.size(); i < size; i++) {
if (cls == activityStack.peek().getClass()) {
return true;
var i = 0
val size = activityStack.size
while (i < size) {
if (cls == activityStack.peek().javaClass) {
return true
}
i++
}
}
return false;
return false
}
/**
......@@ -160,22 +144,38 @@ public class ActivityManager {
* @param context 上下文
* @param isBackground 是否开开启后台运行
*/
public void appExit(Context context, Boolean isBackground) {
fun appExit(context: Context, isBackground: Boolean?) {
try {
finishAllActivity();
android.app.ActivityManager activityMgr = (android.app.ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
activityMgr.restartPackage(context.getPackageName());
} catch (Exception e) {
finishAllActivity()
val activityMgr =
context.getSystemService(Context.ACTIVITY_SERVICE) as android.app.ActivityManager
activityMgr.restartPackage(context.packageName)
} catch (e: Exception) {
} finally {
// 注意,如果您有后台程序运行,请不要支持此句子
if (!isBackground) {
System.exit(0);
if ((!isBackground!!)!!) {
System.exit(0)
}
}
}
public boolean isActivityStackEmpty(){
return activityStack.empty();
companion object {
private lateinit var activityStack: Stack<Activity>
@Volatile
private var instance: ActivityManager? = null
fun getInstance(): ActivityManager? {
if (instance == null) {
synchronized(ActivityManager::class.java) {
if (instance == null) {
instance = ActivityManager()
activityStack = Stack()
}
}
}
return instance
}
}
}
package com.fly.tour.common.manager;
import android.content.Context;
import com.fly.tour.common.R;
import com.fly.tour.common.util.log.KLog;
import com.fly.tour.db.dao.NewsDetailDao;
import com.fly.tour.db.dao.NewsTypeDao;
import com.fly.tour.db.entity.NewsDetail;
import com.fly.tour.db.entity.NewsType;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.List;
/**
* Description: <NewsDBManager><br>
* Author: mxdl<br>
* Date: 2019/5/28<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public class NewsDBManager {
public static final String TAG = NewsDBManager.class.getSimpleName();
private static NewsDBManager newsDBManager;
private Context mContext;
private NewsDBManager(Context context) {
mContext = context;
}
public static NewsDBManager getInstance(Context context) {
if (newsDBManager == null) {
synchronized (NewsDBManager.class) {
if (newsDBManager == null) {
newsDBManager = new NewsDBManager(context);
}
}
}
return newsDBManager;
}
public void initNewsDB() {
NewsTypeDao mNewsTypeDao = new NewsTypeDao(mContext);
if (mNewsTypeDao.isEmpty()) {
Gson gson = new Gson();
Type type = new TypeToken<List<NewsType>>() {
}.getType();
List<NewsType> mListNewsType = gson.fromJson(getStringByResId(R.raw.news_type), type);
mNewsTypeDao.addListNewStype(mListNewsType);
}
NewsDetailDao newsDetailDao = new NewsDetailDao(mContext);
if (newsDetailDao.isEmpty()) {
Gson gson = new Gson();
Type type = new TypeToken<List<NewsDetail>>() {
}.getType();
List<NewsDetail> newsDetailList = gson.fromJson(getStringByResId(R.raw.news_detail), type);
newsDetailDao.addListNewsDetail(newsDetailList);
}
}
private String getStringByResId(int resid) {
InputStream inputStream = mContext.getResources().openRawResource(resid);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
StringBuilder stringBuilder = new StringBuilder();
String line = null;
try {
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
return stringBuilder.toString();
}
public List<NewsType> getListNewsType() {
return new NewsTypeDao(mContext).getListNewsType();
}
}
package com.fly.tour.common.manager
import android.content.Context
import com.fly.tour.common.R
import com.fly.tour.db.dao.NewsDetailDao
import com.fly.tour.db.dao.NewsTypeDao
import com.fly.tour.db.entity.NewsDetail
import com.fly.tour.db.entity.NewsType
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
/**
* Description: <NewsDBManager><br>
* Author: mxdl<br>
* Date: 2019/5/28<br>
* Version: V1.0.0<br>
* Update: <br>
</NewsDBManager> */
class NewsDBManager private constructor(private val mContext: Context) {
fun getListNewsType(): List<NewsType>? {
return NewsTypeDao(mContext).getListNewsType()
}
fun initNewsDB() {
val mNewsTypeDao = NewsTypeDao(mContext)
if (mNewsTypeDao.isEmpty()) {
val gson = Gson()
val type = object : TypeToken<List<NewsType>>() {
}.type
val mListNewsType =
gson.fromJson<List<NewsType>>(getStringByResId(R.raw.news_type), type)
mNewsTypeDao.addListNewStype(mListNewsType)
}
val newsDetailDao = NewsDetailDao(mContext)
if (newsDetailDao.isEmpty) {
val gson = Gson()
val type = object : TypeToken<List<NewsDetail>>() {
}.type
val newsDetailList =
gson.fromJson<List<NewsDetail>>(getStringByResId(R.raw.news_detail), type)
newsDetailDao.addListNewsDetail(newsDetailList)
}
}
private fun getStringByResId(resid: Int): String {
val inputStream = mContext.resources.openRawResource(resid)
val inputStreamReader = InputStreamReader(inputStream)
val bufferedReader = BufferedReader(inputStreamReader)
val stringBuilder = StringBuilder()
var line: String? = null
try {
// while (({line = bufferedReader.readLine()}) != null) {
// stringBuilder.append(line)
// }
//以上为Java中的写法,在有些机型中会造成内存溢出,下面为Kotlin中的通用写法
val text: List<String> = bufferedReader.readLines()
for (line in text) {
stringBuilder.append(line)
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
bufferedReader.close()
inputStreamReader.close()
inputStream.close()
}
return stringBuilder.toString()
}
companion object {
val TAG = NewsDBManager::class.java!!.getSimpleName()
private var newsDBManager: NewsDBManager? = null
fun getInstance(context: Context): NewsDBManager? {
if (newsDBManager == null) {
synchronized(NewsDBManager::class.java) {
if (newsDBManager == null) {
newsDBManager = NewsDBManager(context)
}
}
}
return newsDBManager
}
}
}
package com.fly.tour.common.mvp;
import android.content.Context;
import com.trello.rxlifecycle2.LifecycleProvider;
/**
* Description: <BaseModel><br>
* Author: mxdl<br>
* Date: 2018/3/18<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public class BaseModel {
private Context mContext;
private LifecycleProvider lifecycle;
public BaseModel(Context context) {
mContext = context;
}
public void injectLifecycle(LifecycleProvider lifecycle) {
this.lifecycle = lifecycle;
}
public LifecycleProvider getLifecycle() {
return lifecycle;
}
public Context getContext() {
return mContext;
}
public void destory(){}
}
package com.fly.tour.common.mvp
import android.content.Context
import com.trello.rxlifecycle2.LifecycleProvider
/**
* Description: <BaseModel><br>
* Author: mxdl<br>
* Date: 2018/3/18<br>
* Version: V1.0.0<br>
* Update: <br>
</BaseModel> */
open class BaseModel(val context: Context) {
var lifecycle: LifecycleProvider<*>? = null
private set
fun injectLifecycle(lifecycle: LifecycleProvider<*>) {
this.lifecycle = lifecycle
}
fun destory() {}
}
package com.fly.tour.common.mvp;
import android.content.Context;
import com.trello.rxlifecycle2.LifecycleProvider;
/**
* Description: <BasePresenter><br>
* Author: mxdl<br>
* Date: 2018/1/15<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public abstract class BasePresenter<M extends BaseModel, V> {
protected Context mContext;
protected V mView;
protected M mModel;
public BasePresenter(Context context) {
mContext = context;
}
public void attach(V view) {
attachView(view);
attachModel();
}
public void detach() {
detachView();
detachModel();
}
public void attachView(V view) {
mView = view;
}
public void detachView() {
mView = null;
}
public void attachModel() {
mModel = initModel();
}
public void detachModel() {
mModel.destory();
mModel = null;
}
public abstract M initModel();
public void injectLifecycle(LifecycleProvider lifecycle) {
if (mModel != null) {
mModel.injectLifecycle(lifecycle);
}
}
}
package com.fly.tour.common.mvp
import android.content.Context
import com.trello.rxlifecycle2.LifecycleProvider
/**
* Description: <BasePresenter><br>
* Author: mxdl<br>
* Date: 2018/1/15<br>
* Version: V1.0.0<br>
* Update: <br>
</BasePresenter> */
abstract class BasePresenter<M : BaseModel, V>(protected var mContext: Context) {
protected var mView: V? = null
protected var mModel: M? = null
fun attach(view: V) {
attachView(view)
attachModel()
}
fun detach() {
detachView()
detachModel()
}
fun attachView(view: V) {
mView = view
}
fun detachView() {
mView = null
}
fun attachModel() {
mModel = initModel()
}
fun detachModel() {
mModel?.destory()
mModel = null
}
abstract fun initModel(): M
fun injectLifecycle(lifecycle: LifecycleProvider<*>) {
mModel?.injectLifecycle(lifecycle)
}
}
package com.fly.tour.common.mvp;
package com.fly.tour.common.mvp
/**
* Description: <基本的刷新数据协议><br>
......@@ -6,60 +6,60 @@ package com.fly.tour.common.mvp;
* Date: 2018/2/25<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public interface BaseRefreshContract {
</基本的刷新数据协议> */
interface BaseRefreshContract {
interface Presenter {
/**
* 刷新数据
*/
void refreshData();
fun refreshData()
/**
* 加载更多
*/
void loadMoreData();
fun loadMoreData()
}
interface View extends BaseView{
interface View : BaseView {
/**
* 是否启用下拉刷新
* @param b
*/
void enableRefresh(boolean b);
fun enableRefresh(b: Boolean)
/**
*是否启用上拉加载更多
* 是否启用上拉加载更多
*/
void enableLoadMore(boolean b);
fun enableLoadMore(b: Boolean)
/**
*刷新回调
* 刷新回调
*/
void onRefreshEvent();
fun onRefreshEvent()
/**
* 加载更多的回调
*/
void onLoadMoreEvent();
fun onLoadMoreEvent()
/**
* 自动加载的事件
*/
void onAutoLoadEvent();
fun onAutoLoadEvent()
/**
* 停止刷新
*/
void stopRefresh();
fun stopRefresh()
/**
* 停止加载更多
*/
void stopLoadMore();
fun stopLoadMore()
/**
* 自动加载数据
*/
void autoLoadData();
fun autoLoadData()
}
}
package com.fly.tour.common.mvp;
package com.fly.tour.common.mvp
import android.content.Context;
import android.content.Context
/**
* Description: <BaseRefreshPresenter><br>
......@@ -8,9 +8,5 @@ import android.content.Context;
* Date: 2018/2/26<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public abstract class BaseRefreshPresenter<M extends BaseModel,V extends BaseRefreshView<T>,T> extends BasePresenter<M,V> implements BaseRefreshContract.Presenter{
public BaseRefreshPresenter(Context context) {
super(context);
}
}
</BaseRefreshPresenter> */
abstract class BaseRefreshPresenter<M : BaseModel, V : BaseRefreshView<T>, T>(context: Context) : BasePresenter<M, V>(context), BaseRefreshContract.Presenter
package com.fly.tour.common.mvp;
import java.util.List;
package com.fly.tour.common.mvp
/**
* Description: <BaseRefreshView><br>
......@@ -8,10 +6,11 @@ import java.util.List;
* Date: 2018/2/26<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public interface BaseRefreshView<T> extends BaseRefreshContract.View {
</BaseRefreshView> */
interface BaseRefreshView<T> : BaseRefreshContract.View {
//刷新数据
void refreshData(List<T> data);
fun refreshData(data: List<T>)
//加载更多
void loadMoreData(List<T> data);
fun loadMoreData(data: List<T>)
}
package com.fly.tour.common.mvp;
package com.fly.tour.common.mvp
/**
* Description: <BaseView><br>
......@@ -6,10 +6,9 @@ package com.fly.tour.common.mvp;
* Date: 2018/3/25<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public interface BaseView extends ILoadView,INoDataView,ITransView,INetErrView{
void initView();
void initListener();
void initData();
void finishActivity();
</BaseView> */
interface BaseView : ILoadView, INoDataView, ITransView, INetErrView {
fun initListener()
fun initData()
fun finishActivity()
}
package com.fly.tour.common.mvp;
package com.fly.tour.common.mvp
/**
* Description: <ILoadView><br>
......@@ -6,10 +6,11 @@ package com.fly.tour.common.mvp;
* Date: 2018/2/26<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public interface ILoadView {
</ILoadView> */
interface ILoadView {
//显示初始加载的View,初始进来加载数据需要显示的View
void showInitLoadView();
fun showInitLoadView()
//隐藏初始加载的View
void hideInitLoadView();
fun hideInitLoadView()
}
package com.fly.tour.common.mvp;
package com.fly.tour.common.mvp
/**
* Description: <INetErrView><br>
......@@ -6,10 +6,11 @@ package com.fly.tour.common.mvp;
* Date: 2018/2/26<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public interface INetErrView {
</INetErrView> */
interface INetErrView {
//显示网络错误的View
void showNetWorkErrView();
fun showNetWorkErrView()
//隐藏网络错误的View
void hideNetWorkErrView();
fun hideNetWorkErrView()
}
package com.fly.tour.common.mvp;
package com.fly.tour.common.mvp
import android.support.annotation.DrawableRes;
import android.support.annotation.DrawableRes
/**
* Description: <INoDataView><br>
......@@ -8,13 +8,14 @@ import android.support.annotation.DrawableRes;
* Date: 2018/3/11<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public interface INoDataView {
</INoDataView> */
interface INoDataView {
//显示无数据View
void showNoDataView();
fun showNoDataView()
//隐藏无数据View
void hideNoDataView();
fun hideNoDataView()
//显示指定资源的无数据View
void showNoDataView(@DrawableRes int resid);
fun showNoDataView(@DrawableRes resid: Int)
}
package com.fly.tour.common.mvp;
package com.fly.tour.common.mvp
/**
* Description: <ITransView><br>
......@@ -6,10 +6,11 @@ package com.fly.tour.common.mvp;
* Date: 2018/2/26<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public interface ITransView {
</ITransView> */
interface ITransView {
//显示背景透明小菊花View,例如删除操作
void showTransLoadingView();
fun showTransLoadingView()
//隐藏背景透明小菊花View
void hideTransLoadingView();
fun hideTransLoadingView()
}
package com.fly.tour.common.util;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
/**
* @Description
* @Author guojingbu
* @Date 2019/3/12
*/
public class AnimationUtils {
/**
* 从控件所在位置移动到控件的底部
*
* @return
*/
public static TranslateAnimation moveToBottom() {
TranslateAnimation hiddenAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f);
hiddenAction.setDuration(300);
return hiddenAction;
}
public static TranslateAnimation moveToLocation() {
TranslateAnimation visibleAction = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0.0f);
visibleAction.setDuration(300);
return visibleAction;
}
}
package com.fly.tour.common.util
import android.view.animation.Animation
import android.view.animation.TranslateAnimation
/**
* @Description
* @Author guojingbu
* @Date 2019/3/12
*/
object AnimationUtils {
/**
* 从控件所在位置移动到控件的底部
*
* @return
*/
fun moveToBottom(): TranslateAnimation {
val hiddenAction = TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f)
hiddenAction.duration = 300
return hiddenAction
}
fun moveToLocation(): TranslateAnimation {
val visibleAction = TranslateAnimation(Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0.0f)
visibleAction.duration = 300
return visibleAction
}
}
package com.fly.tour.common.util;
import android.support.design.widget.AppBarLayout;
/**
* Description: <AppBarStateChangeListener><br>
* Author: mxdl<br>
* Date: 2019/1/21<br>
* Version: V1.0.0<br>
* Update: <br>
*/
public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener {
public enum State {
EXPANDED,
COLLAPSED,
IDLE
}
private State mCurrentState = State.IDLE;
@Override
public final void onOffsetChanged(AppBarLayout appBarLayout, int i) {
if (i == 0) {
if (mCurrentState != State.EXPANDED) {
onStateChanged(appBarLayout, State.EXPANDED);
}
mCurrentState = State.EXPANDED;
} else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) {
if (mCurrentState != State.COLLAPSED) {
onStateChanged(appBarLayout, State.COLLAPSED);
}
mCurrentState = State.COLLAPSED;
} else {
if (mCurrentState != State.IDLE) {
onStateChanged(appBarLayout, State.IDLE);
}
mCurrentState = State.IDLE;
}
}
public abstract void onStateChanged(AppBarLayout appBarLayout, State state);
}
\ No newline at end of file
package com.fly.tour.common.util;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Looper;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Properties;
import java.util.TreeSet;
/**
* 线程未捕获异常控制器是用来处理未捕获异常的。
* <p>
* UncaughtException处理类,当程序发生Uncaught异常的时候,由该类来接管程序,并记录发送错误报告.
*/
public class CrashHandler implements Thread.UncaughtExceptionHandler {
/**
* Debug Log Tag
*/
public static final String TAG = "YESWAY-CrashHandler";
/**
* 是否开启日志输出, 在Debug状态下开启, 在Release状态下关闭以提升程序性能
*/
public static final boolean DEBUG = true;
/**
* CrashHandler实例
*/
private static CrashHandler mCrashHandler;
/**
* 程序的Context对象
*/
private Context mContext;
/**
* 系统默认的UncaughtException处理类
*/
private Thread.UncaughtExceptionHandler mDefaultHandler;
/**
* 使用Properties来保存设备的信息和错误堆栈信息
*/
private Properties mDeviceCrashInfo = new Properties();
/**
* 版本
*/
private static final String VERSION_NAME = "versionName";
/**
* 版本号
*/
private static final String VERSION_CODE = "versionCode";
/**
* 堆栈名
*/
private static final String STACK_TRACE = "STACK_TRACE";
/**
* 错误报告文件的扩展名
*/
private static final String CRASH_REPORTER_EXTENSION = ".txt";
/**
* 保证只有一个CrashHandler实例
*/
private CrashHandler() {
}
/**
* 获取CrashHandler实例 ,单例模式
*/
public static CrashHandler getInstance() {
if (mCrashHandler == null) {
mCrashHandler = new CrashHandler();
}
return mCrashHandler;
}
/**
* 初始化,注册Context对象, 获取系统默认的UncaughtException处理器, 设置该CrashHandler为程序的默认处理器
*
* @param ctx
*/
public void init(Context ctx) {
mContext = ctx;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* 当UncaughtException发生时会转入该函数来处理
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
// 如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
} else {
// MobclickAgent.reportError(context, ex);
// 退出程序
ToastUtil.showToast("发生异常,已重启应用");
// EnvironmentUtil.openApp(mContext, SplashActivity.class.getName());
// Intent intent = new Intent(Intent.ACTION_MAIN);
// intent.addCategory(Intent.CATEGORY_LAUNCHER);
// ComponentName cn = new ComponentName(mContext.getPackageName(), className);
// intent.setComponent(cn);
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
// mContext.startActivity(intent);
String packageName = mContext.getPackageName();
// Log.v("TEST","packageName:"+packageName);
Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(packageName);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
mContext.startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
}
}
private static void openApp(Context context, String className) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
ComponentName cn = new ComponentName(context.getPackageName(), className);
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
*
* @param ex
* @return true:如果处理了该异常信息;否则返回false
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return true;
}
// final String msg = ex.getLocalizedMessage();
// 使用Toast来显示异常信息
new Thread() {
@Override
public void run() {
// Toast 显示需要出现在一个线程的消息队列中
Looper.prepare();
ToastUtil.showToast("程序异常,请重启应用");
Looper.loop();
// 程序出现异常,下次程序进入默认值更改为我的主页
// SaveSharedPreference.setSharedPreferenceInt(mContext,
// "lastSelect", R.id.rb_index_page);
}
}.start();
// 收集设备信息
collectCrashDeviceInfo(mContext);
// 保存错误报告文件
// saveCrashInfoToFile(ex);
// 发送错误报告到服务器
// sendCrashReportsToServer(mContext);
return true;
}
/**
* 收集程序崩溃的设备信息
*
* @param ctx
*/
public void collectCrashDeviceInfo(Context ctx) {
try {
PackageManager pm = ctx.getPackageManager();
PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
mDeviceCrashInfo.put(VERSION_NAME, pi.versionName == null ? "not set" : pi.versionName);
mDeviceCrashInfo.put(VERSION_CODE, pi.versionCode);
}
} catch (Exception e) {
Log.e(TAG, "Error while collect package info" + e);
}
// 使用反射来收集设备信息.在Build类中包含各种设备信息,
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
try {
// setAccessible(boolean flag)
// 将此对象的 accessible 标志设置为指示的布尔值。
// 通过设置Accessible属性为true,才能对私有变量进行访问,不然会得到一个IllegalAccessException的异常
field.setAccessible(true);
mDeviceCrashInfo.put(field.getName(), field.get(null));
if (DEBUG) {
Log.d(TAG, field.getName() + " : " + field.get(null));
}
} catch (Exception e) {
Log.e(TAG, "Error while collect crash info" + e);
}
}
}
/**
* 保存错误信息到文件中
*
* @param ex
* @return
*/
private String saveCrashInfoToFile(Throwable ex) {
Writer info = new StringWriter();
PrintWriter printWriter = new PrintWriter(info);
// printStackTrace(PrintWriter s)
// 将此 throwable 及其追踪输出到指定的 PrintWriter
ex.printStackTrace(printWriter);
// getCause() 返回此 throwable 的 cause;如果 cause 不存在或未知,则返回 null。
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
// toString() 以字符串的形式返回该缓冲区的当前值。
String result = info.toString();
printWriter.close();
mDeviceCrashInfo.put(STACK_TRACE, result);
try {
String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
String fileName = "crash-" + timestamp + CRASH_REPORTER_EXTENSION;
// 保存文件
File directory = new File(EnvironmentUtil.Storage.getExternalCacheDir(mContext), "logs");
if (!directory.exists()) {
directory.mkdirs();
}
File file = new File(directory, fileName);
FileOutputStream trace = new FileOutputStream(file);
Log.e(TAG, new String(result.getBytes()));
// 写入
trace.write(result.getBytes());
trace.flush();
trace.close();
return fileName;
} catch (Exception e) {
Log.e(TAG, e.toString());
}
return null;
}
/**
* 把错误报告发送给服务器,包含新产生的和以前没发送的.
*
* @param ctx
*/
private void sendCrashReportsToServer(Context ctx) {
String[] crFiles = getCrashReportFiles(ctx);
if (crFiles != null && crFiles.length > 0) {
TreeSet<String> sortedFiles = new TreeSet<String>();
sortedFiles.addAll(Arrays.asList(crFiles));
for (String fileName : sortedFiles) {
File cr = new File(ctx.getFilesDir(), fileName);
postReport(cr);
cr.delete();// 删除已发送的报告
}
}
}
/**
* 获取错误报告文件名
*
* @param ctx
* @return
*/
private String[] getCrashReportFiles(Context ctx) {
File filesDir = ctx.getFilesDir();
// 实现FilenameFilter接口的类实例可用于过滤器文件名
FilenameFilter filter = new FilenameFilter() {
// accept(File dir, String name)
// 测试指定文件是否应该包含在某一文件列表中。
public boolean accept(File dir, String name) {
return name.endsWith(CRASH_REPORTER_EXTENSION);
}
};
// list(FilenameFilter filter)
// 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录
return filesDir.list(filter);
}
private void postReport(File file) {
// 使用HTTP Post 发送错误报告到服务器
// 这里不再详述,开发者可以根据OPhoneSDN上的其他网络操作
}
/**
* 在程序启动时候, 可以调用该函数来发送以前没有发送的报告
*/
public void sendPreviousReportsToServer() {
sendCrashReportsToServer(mContext);
}
}
package com.fly.tour.common.util
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.Build
import android.os.Looper
import android.util.Log
import java.io.File
import java.io.FileOutputStream
import java.io.FilenameFilter
import java.io.PrintWriter
import java.io.StringWriter
import java.io.Writer
import java.lang.reflect.Field
import java.text.SimpleDateFormat
import java.util.Arrays
import java.util.Date
import java.util.Properties
import java.util.TreeSet
/**
* 线程未捕获异常控制器是用来处理未捕获异常的。
*
*
* UncaughtException处理类,当程序发生Uncaught异常的时候,由该类来接管程序,并记录发送错误报告.
*/
class CrashHandler
/**
* 保证只有一个CrashHandler实例
*/
private constructor() : Thread.UncaughtExceptionHandler {
/**
* 程序的Context对象
*/
private var mContext: Context? = null
/**
* 系统默认的UncaughtException处理类
*/
private var mDefaultHandler: Thread.UncaughtExceptionHandler? = null
/**
* 使用Properties来保存设备的信息和错误堆栈信息
*/
private val mDeviceCrashInfo = Properties()
/**
* 初始化,注册Context对象, 获取系统默认的UncaughtException处理器, 设置该CrashHandler为程序的默认处理器
*
* @param ctx
*/
fun init(ctx: Context) {
mContext = ctx
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler()
Thread.setDefaultUncaughtExceptionHandler(this)
}
/**
* 当UncaughtException发生时会转入该函数来处理
*/
override fun uncaughtException(thread: Thread, ex: Throwable) {
if (!handleException(ex) && mDefaultHandler != null) {
// 如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler!!.uncaughtException(thread, ex)
} else {
// MobclickAgent.reportError(context, ex);
// 退出程序
ToastUtil.showToast("发生异常,已重启应用")
// EnvironmentUtil.openApp(mContext, SplashActivity.class.getName());
// Intent intent = new Intent(Intent.ACTION_MAIN);
// intent.addCategory(Intent.CATEGORY_LAUNCHER);
// ComponentName cn = new ComponentName(mContext.getPackageName(), className);
// intent.setComponent(cn);
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
// mContext.startActivity(intent);
val packageName = mContext!!.packageName
// Log.v("TEST","packageName:"+packageName);
val intent = mContext!!.packageManager.getLaunchIntentForPackage(packageName)
intent!!.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
mContext!!.startActivity(intent)
android.os.Process.killProcess(android.os.Process.myPid())
}
}
/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
*
* @param ex
* @return true:如果处理了该异常信息;否则返回false
*/
private fun handleException(ex: Throwable?): Boolean {
if (ex == null) {
return true
}
// final String msg = ex.getLocalizedMessage();
// 使用Toast来显示异常信息
object : Thread() {
override fun run() {
// Toast 显示需要出现在一个线程的消息队列中
Looper.prepare()
ToastUtil.showToast("程序异常,请重启应用")
Looper.loop()
// 程序出现异常,下次程序进入默认值更改为我的主页
// SaveSharedPreference.setSharedPreferenceInt(mContext,
// "lastSelect", R.id.rb_index_page);
}
}.start()
// 收集设备信息
collectCrashDeviceInfo(mContext)
// 保存错误报告文件
// saveCrashInfoToFile(ex);
// 发送错误报告到服务器
// sendCrashReportsToServer(mContext);
return true
}
/**
* 收集程序崩溃的设备信息
*
* @param ctx
*/
fun collectCrashDeviceInfo(ctx: Context?) {
try {
val pm = ctx!!.packageManager
val pi = pm.getPackageInfo(ctx.packageName, PackageManager.GET_ACTIVITIES)
if (pi != null) {
mDeviceCrashInfo[VERSION_NAME] = if (pi.versionName == null) "not set" else pi.versionName
mDeviceCrashInfo[VERSION_CODE] = pi.versionCode
}
} catch (e: Exception) {
Log.e(TAG, "Error while collect package info$e")
}
// 使用反射来收集设备信息.在Build类中包含各种设备信息,
val fields = Build::class.java!!.getDeclaredFields()
for (field in fields) {
try {
// setAccessible(boolean flag)
// 将此对象的 accessible 标志设置为指示的布尔值。
// 通过设置Accessible属性为true,才能对私有变量进行访问,不然会得到一个IllegalAccessException的异常
field.setAccessible(true)
mDeviceCrashInfo[field.getName()] = field.get(null)
if (DEBUG) {
Log.d(TAG, field.getName() + " : " + field.get(null))
}
} catch (e: Exception) {
Log.e(TAG, "Error while collect crash info$e")
}
}
}
/**
* 保存错误信息到文件中
*
* @param ex
* @return
*/
private fun saveCrashInfoToFile(ex: Throwable): String? {
val info = StringWriter()
val printWriter = PrintWriter(info)
// printStackTrace(PrintWriter s)
// 将此 throwable 及其追踪输出到指定的 PrintWriter
ex.printStackTrace(printWriter)
// getCause() 返回此 throwable 的 cause;如果 cause 不存在或未知,则返回 null。
var cause: Throwable? = ex.cause
while (cause != null) {
cause.printStackTrace(printWriter)
cause = cause.cause
}
// toString() 以字符串的形式返回该缓冲区的当前值。
val result = info.toString()
printWriter.close()
mDeviceCrashInfo[STACK_TRACE] = result
try {
val timestamp = SimpleDateFormat("yyyyMMddHHmmss").format(Date())
val fileName = "crash-$timestamp$CRASH_REPORTER_EXTENSION"
// 保存文件
val directory = File(EnvironmentUtil.Storage.getExternalCacheDir(mContext!!), "logs")
if (!directory.exists()) {
directory.mkdirs()
}
val file = File(directory, fileName)
val trace = FileOutputStream(file)
Log.e(TAG, String(result.toByteArray()))
// 写入
trace.write(result.toByteArray())
trace.flush()
trace.close()
return fileName
} catch (e: Exception) {
Log.e(TAG, e.toString())
}
return null
}
/**
* 把错误报告发送给服务器,包含新产生的和以前没发送的.
*
* @param ctx
*/
private fun sendCrashReportsToServer(ctx: Context?) {
val crFiles = getCrashReportFiles(ctx!!)
if (crFiles != null && crFiles.size > 0) {
val sortedFiles = TreeSet<String>()
sortedFiles.addAll(Arrays.asList(*crFiles))
for (fileName in sortedFiles) {
val cr = File(ctx.filesDir, fileName)
postReport(cr)
cr.delete()// 删除已发送的报告
}
}
}
/**
* 获取错误报告文件名
*
* @param ctx
* @return
*/
private fun getCrashReportFiles(ctx: Context): Array<String>? {
val filesDir = ctx.filesDir
// 实现FilenameFilter接口的类实例可用于过滤器文件名
val filter = FilenameFilter { dir, name -> // accept(File dir, String name)
// 测试指定文件是否应该包含在某一文件列表中。
name.endsWith(CRASH_REPORTER_EXTENSION)
}
// list(FilenameFilter filter)
// 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录
return filesDir.list(filter)
}
private fun postReport(file: File) {
// 使用HTTP Post 发送错误报告到服务器
// 这里不再详述,开发者可以根据OPhoneSDN上的其他网络操作
}
/**
* 在程序启动时候, 可以调用该函数来发送以前没有发送的报告
*/
fun sendPreviousReportsToServer() {
sendCrashReportsToServer(mContext)
}
companion object {
/**
* Debug Log Tag
*/
val TAG = "YESWAY-CrashHandler"
/**
* 是否开启日志输出, 在Debug状态下开启, 在Release状态下关闭以提升程序性能
*/
val DEBUG = true
/**
* CrashHandler实例
*/
private var mCrashHandler: CrashHandler? = null
/**
* 版本
*/
private val VERSION_NAME = "versionName"
/**
* 版本号
*/
private val VERSION_CODE = "versionCode"
/**
* 堆栈名
*/
private val STACK_TRACE = "STACK_TRACE"
/**
* 错误报告文件的扩展名
*/
private val CRASH_REPORTER_EXTENSION = ".txt"
/**
* 获取CrashHandler实例 ,单例模式
*/
val instance: CrashHandler
get() {
if (mCrashHandler == null) {
mCrashHandler = CrashHandler()
}
return mCrashHandler as CrashHandler
}
private fun openApp(context: Context, className: String) {
val intent = Intent(Intent.ACTION_MAIN)
intent.addCategory(Intent.CATEGORY_LAUNCHER)
val cn = ComponentName(context.packageName, className)
intent.component = cn
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
context.startActivity(intent)
}
}
}
package com.fly.tour.common.util;
package com.fly.tour.common.util
import android.content.Context;
import android.content.Context
import com.fly.tour.common.BaseApplication;
import com.fly.tour.common.BaseApplication
/**
* Description: <单位转换工具类><br>
......@@ -10,38 +10,38 @@ import com.fly.tour.common.BaseApplication;
* Date: 2018/6/11<br>
* Version: V1.0.0<br>
* Update: <br>
* <ul>
*
* <h1>功能列表:</h1>
* <li>1. dp转px</li>
* <li>2. px转dp</li>
* <li>3. sp转px</li>
* <li>4. px转sp</li>
* </ul>
*/
public class DisplayUtil {
private static Context context = BaseApplication.getInstance().getApplicationContext();
* * 1. dp转px
* * 2. px转dp
* * 3. sp转px
* * 4. px转sp
*
</单位转换工具类> */
object DisplayUtil {
private val context = BaseApplication.instance!!.getApplicationContext()
/**
* 将px值转换为dip或dp值,保证尺寸大小不变
*
* @param pxValue
* @param scale
* (DisplayMetrics类中属性density)
* (DisplayMetrics类中属性density)
* @return
*/
public static int px2dip(float pxValue, float scale) {
return (int) (pxValue / scale + 0.5f);
fun px2dip(pxValue: Float, scale: Float): Int {
return (pxValue / scale + 0.5f).toInt()
}
/**
* 将px值转换为dip或dp值,保证尺寸大小不变
*
* @param pxValue
* (DisplayMetrics类中属性density)
* (DisplayMetrics类中属性density)
* @return
*/
public static int px2dip(float pxValue) {
return (int) (pxValue / context.getResources().getDisplayMetrics().density + 0.5f);
fun px2dip(pxValue: Float): Int {
return (pxValue / context.getResources().getDisplayMetrics().density + 0.5f).toInt()
}
/**
......@@ -49,11 +49,11 @@ public class DisplayUtil {
*
* @param dipValue
* @param scale
* (DisplayMetrics类中属性density)
* (DisplayMetrics类中属性density)
* @return
*/
public static int dip2px(float dipValue, float scale) {
return (int) (dipValue * scale + 0.5f);
fun dip2px(dipValue: Float, scale: Float): Int {
return (dipValue * scale + 0.5f).toInt()
}
/**
......@@ -62,8 +62,8 @@ public class DisplayUtil {
* @param dipValue
* @return
*/
public static int dip2px(float dipValue) {
return (int) (dipValue * context.getResources().getDisplayMetrics().density + 0.5f);
fun dip2px(dipValue: Float): Int {
return (dipValue * context.getResources().getDisplayMetrics().density + 0.5f).toInt()
}
/**
......@@ -71,11 +71,11 @@ public class DisplayUtil {
*
* @param pxValue
* @param fontScale
* (DisplayMetrics类中属性scaledDensity)
* (DisplayMetrics类中属性scaledDensity)
* @return
*/
public static int px2sp(float pxValue, float fontScale) {
return (int) (pxValue / fontScale + 0.5f);
fun px2sp(pxValue: Float, fontScale: Float): Int {
return (pxValue / fontScale + 0.5f).toInt()
}
/**
......@@ -84,8 +84,8 @@ public class DisplayUtil {
* @param pxValue
* @return
*/
public static int px2sp(float pxValue) {
return (int) (pxValue / context.getResources().getDisplayMetrics().scaledDensity + 0.5f);
fun px2sp(pxValue: Float): Int {
return (pxValue / context.getResources().getDisplayMetrics().scaledDensity + 0.5f).toInt()
}
/**
......@@ -93,11 +93,11 @@ public class DisplayUtil {
*
* @param spValue
* @param fontScale
* (DisplayMetrics类中属性scaledDensity)
* (DisplayMetrics类中属性scaledDensity)
* @return
*/
public static int sp2px(float spValue, float fontScale) {
return (int) (spValue * fontScale + 0.5f);
fun sp2px(spValue: Float, fontScale: Float): Int {
return (spValue * fontScale + 0.5f).toInt()
}
/**
......@@ -106,7 +106,7 @@ public class DisplayUtil {
* @param spValue
* @return
*/
public static int sp2px(float spValue) {
return (int) (spValue * context.getResources().getDisplayMetrics().scaledDensity + 0.5f);
fun sp2px(spValue: Float): Int {
return (spValue * context.getResources().getDisplayMetrics().scaledDensity + 0.5f).toInt()
}
}
\ No newline at end of file
package com.fly.tour.common.util
import android.text.TextUtils
import java.io.BufferedInputStream
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.IOException
import java.util.regex.Matcher
import java.util.regex.Pattern
/**
* Description: <FileUtil><br>
* Author: mxdl<br>
* Date: 2018/7/13<br>
* Version: V1.0.0<br>
* Update: <br>
</FileUtil> */
object FileUtil {
fun isImageFile(url: String): Boolean {
if (TextUtils.isEmpty(url)) {
return false
}
val reg = ".+(\\.jpeg|\\.jpg|\\.gif|\\.bmp|\\.png).*"
val pattern = Pattern.compile(reg)
val matcher = pattern.matcher(url.toLowerCase())
return matcher.find()
}
fun isVideoFile(url: String): Boolean {
if (TextUtils.isEmpty(url)) {
return false
}
val reg = ".+(\\.avi|\\.wmv|\\.mpeg|\\.mp4|\\.mov|\\.mkv|\\.flv|\\.f4v|\\.m4v|\\.rmvb|\\.rm|\\.rmvb|\\.3gp|\\.dat|\\.ts|\\.mts|\\.vob).*"
val pattern = Pattern.compile(reg)
val matcher = pattern.matcher(url.toLowerCase())
return matcher.find()
}
fun isUrl(url: String): Boolean {
if (TextUtils.isEmpty(url)) {
return false
}
val reg = "(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]"
return url.matches(reg.toRegex())
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册