├── .gitignore
├── README.md
├── apk
├── Java_release_v1.0.0(002).apk
└── Kotlin_release_v1.0.0(001).apk
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── java
├── .gitignore
├── build.gradle
├── proguard-rules.pro
├── proguardMapping.txt
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── android
│ │ └── java
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── android
│ │ │ ├── base
│ │ │ ├── BaseApplication.java
│ │ │ ├── DontSwipeBack.java
│ │ │ ├── FrameFragment.java
│ │ │ ├── MainActivity.java
│ │ │ ├── UtilFragment.java
│ │ │ └── WidgetFragment.java
│ │ │ ├── frame
│ │ │ ├── TestLeakActivity.java
│ │ │ ├── guide
│ │ │ │ ├── GuideActivity.java
│ │ │ │ └── SimpleViewAdapter.java
│ │ │ ├── http
│ │ │ │ ├── AATest
│ │ │ │ │ ├── ApiService.java
│ │ │ │ │ ├── TestRetrofitActivity.java
│ │ │ │ │ ├── UrlConstant.java
│ │ │ │ │ ├── WangYiNewsWebviewActivity.java
│ │ │ │ │ └── bean
│ │ │ │ │ │ ├── NewsListBean.java
│ │ │ │ │ │ └── WeatherBean.java
│ │ │ │ ├── CookieJarManage.java
│ │ │ │ ├── ExceptionUtil.java
│ │ │ │ ├── RetrofitFactory.java
│ │ │ │ ├── SSLSocketFactoryUtil.java
│ │ │ │ ├── SchedulerUtil.java
│ │ │ │ ├── converter
│ │ │ │ │ ├── CustomGsonConverterFactory.java
│ │ │ │ │ ├── CustomGsonRequestBodyConverter.java
│ │ │ │ │ ├── CustomGsonResponseBodyConverter.java
│ │ │ │ │ └── 说明.md
│ │ │ │ ├── function
│ │ │ │ │ └── RetryWithDelay.java
│ │ │ │ ├── interceptor
│ │ │ │ │ ├── HttpCacheInterceptor.java
│ │ │ │ │ ├── HttpLogInterceptor.java
│ │ │ │ │ └── MaxRetryInterceptor.java
│ │ │ │ └── model
│ │ │ │ │ ├── BaseListResponse.java
│ │ │ │ │ └── BaseResponse.java
│ │ │ ├── mvc
│ │ │ │ ├── AATest
│ │ │ │ │ ├── TestActivityMvc.java
│ │ │ │ │ ├── TestFragmentMvc.java
│ │ │ │ │ ├── TestMvcActivity.java
│ │ │ │ │ ├── TestMvcFragment.java
│ │ │ │ │ ├── TestMvcListActivity.java
│ │ │ │ │ ├── TestMvcListFragment.java
│ │ │ │ │ ├── TestWebviewActivity.java
│ │ │ │ │ ├── adapter
│ │ │ │ │ │ └── NewsListAdapter.java
│ │ │ │ │ ├── convert
│ │ │ │ │ │ ├── NewsFunction.java
│ │ │ │ │ │ └── WeatherFunction.java
│ │ │ │ │ ├── entity
│ │ │ │ │ │ ├── NewsListBean.java
│ │ │ │ │ │ └── WeatherBean.java
│ │ │ │ │ └── server
│ │ │ │ │ │ ├── ApiHelper.java
│ │ │ │ │ │ ├── ApiService.java
│ │ │ │ │ │ └── Config.java
│ │ │ │ ├── BaseActivity.java
│ │ │ │ ├── BaseFragment.java
│ │ │ │ ├── BaseListActivity.java
│ │ │ │ ├── BaseListFragment.java
│ │ │ │ ├── IBaseListView.java
│ │ │ │ ├── IBaseView.java
│ │ │ │ ├── ImageInterface.java
│ │ │ │ ├── WebviewActivity.java
│ │ │ │ ├── WebviewFragment.java
│ │ │ │ └── extra
│ │ │ │ │ ├── RecyclerView
│ │ │ │ │ ├── CustomLoadMoreView.java
│ │ │ │ │ └── LoadMoreAdapter.java
│ │ │ │ │ └── http
│ │ │ │ │ └── CustomObserver.java
│ │ │ ├── mvp
│ │ │ │ ├── AATest
│ │ │ │ │ ├── TestActivityMvp.java
│ │ │ │ │ ├── TestFragmentMvp.java
│ │ │ │ │ ├── listType
│ │ │ │ │ │ ├── TestMvpListActivity.java
│ │ │ │ │ │ ├── TestMvpListFragment.java
│ │ │ │ │ │ ├── TestMvpListModel.java
│ │ │ │ │ │ ├── TestMvpListPresenter.java
│ │ │ │ │ │ └── TestMvpListView.java
│ │ │ │ │ └── notListType
│ │ │ │ │ │ ├── TestMvpActivity.java
│ │ │ │ │ │ ├── TestMvpFragment.java
│ │ │ │ │ │ ├── TestMvpModel.java
│ │ │ │ │ │ ├── TestMvpPresenter.java
│ │ │ │ │ │ └── TestMvpView.java
│ │ │ │ ├── BaseActivity.java
│ │ │ │ ├── BaseFragment.java
│ │ │ │ ├── BaseListActivity.java
│ │ │ │ ├── BaseListFragment.java
│ │ │ │ ├── BaseListPresenter.java
│ │ │ │ ├── BasePresenter.java
│ │ │ │ ├── CommonBaseActivity.java
│ │ │ │ ├── CommonBaseFragment.java
│ │ │ │ ├── IBaseListView.java
│ │ │ │ ├── IBaseView.java
│ │ │ │ ├── extra
│ │ │ │ │ └── http
│ │ │ │ │ │ └── CustomObserver.java
│ │ │ │ └── 注意点.md
│ │ │ └── mvvm
│ │ │ │ ├── AATest
│ │ │ │ ├── TestActivityMvvm.java
│ │ │ │ ├── TestFragmentMvvm.java
│ │ │ │ ├── convert
│ │ │ │ │ ├── CustomRequestBodyConverter.java
│ │ │ │ │ ├── NewsConverterFactory.java
│ │ │ │ │ ├── NewsResponseBodyConverter.java
│ │ │ │ │ ├── WeatherConverterFactory.java
│ │ │ │ │ └── WeatherResponseBodyConverter.java
│ │ │ │ ├── listType
│ │ │ │ │ ├── TestMvvmListActivity.java
│ │ │ │ │ ├── TestMvvmListActivityViewModel.java
│ │ │ │ │ ├── TestMvvmListFragment.java
│ │ │ │ │ └── TestMvvmListFragmentViewModel.java
│ │ │ │ ├── notListType
│ │ │ │ │ ├── TestMvvmActivity.java
│ │ │ │ │ ├── TestMvvmActivityViewModel.java
│ │ │ │ │ ├── TestMvvmFragment.java
│ │ │ │ │ └── TestMvvmFragmentViewModel.java
│ │ │ │ └── server
│ │ │ │ │ ├── ApiHelper.java
│ │ │ │ │ ├── ApiService.java
│ │ │ │ │ └── Config.java
│ │ │ │ ├── BaseActivity.java
│ │ │ │ ├── BaseFragment.java
│ │ │ │ ├── BaseListActivity.java
│ │ │ │ ├── BaseListFragment.java
│ │ │ │ ├── BaseListViewModel.java
│ │ │ │ ├── BaseViewModel.java
│ │ │ │ ├── BaseViewModelWithData.java
│ │ │ │ ├── CommonBaseActivity.java
│ │ │ │ ├── CommonBaseFragment.java
│ │ │ │ ├── IBaseListView.java
│ │ │ │ ├── IBaseView.java
│ │ │ │ └── extra
│ │ │ │ └── LiveDataEntity
│ │ │ │ ├── DialogConfig.java
│ │ │ │ └── ErrorResponse.java
│ │ │ ├── util
│ │ │ ├── AlertDialogUtil.java
│ │ │ ├── AndroidBug5497Workaround.java
│ │ │ ├── ApkDownloadUtil.java
│ │ │ ├── AudioUtil.java
│ │ │ ├── BrightnessUtil.java
│ │ │ ├── ByteUnit.java
│ │ │ ├── CPUUtil.java
│ │ │ ├── CacheUtil.java
│ │ │ ├── CapturePicture
│ │ │ │ ├── CapturePictureUtil.java
│ │ │ │ ├── TestCaptureGridViewActivity.java
│ │ │ │ ├── TestCaptureListViewActivity.java
│ │ │ │ ├── TestCaptureRecyclerViewActivity.java
│ │ │ │ └── TestCaptureWebViewActivity.java
│ │ │ ├── CheckFastClickUtil.java
│ │ │ ├── CleanUtil.java
│ │ │ ├── CommonLayoutUtil.java
│ │ │ ├── CrashHandler.java
│ │ │ ├── DataDueUtil.java
│ │ │ ├── DateUtil.java
│ │ │ ├── DeviceUtil.java
│ │ │ ├── DigitalUtil.java
│ │ │ ├── DrawableUtil.java
│ │ │ ├── EmptyUtil.java
│ │ │ ├── EncodeUtil.java
│ │ │ ├── ExtraUtil.java
│ │ │ ├── FileUtil.java
│ │ │ ├── HandlerUtil.java
│ │ │ ├── IOUtil.java
│ │ │ ├── IntentUtil.java
│ │ │ ├── JsonUtil.java
│ │ │ ├── KeyboardUtil.java
│ │ │ ├── LayoutParamsUtil.java
│ │ │ ├── LogUtil.java
│ │ │ ├── NetReceiver.java
│ │ │ ├── NetworkUtil.java
│ │ │ ├── NotificationUtil.java
│ │ │ ├── OnAppBarStateChangeListener.java
│ │ │ ├── OnMultiClickListener.java
│ │ │ ├── PhoneUtil.java
│ │ │ ├── PickerViewUtil.java
│ │ │ ├── PinyinUtil.java
│ │ │ ├── SDCardUtil.java
│ │ │ ├── ScreenUtil.java
│ │ │ ├── ShellUtil.java
│ │ │ ├── SizeUtil.java
│ │ │ ├── SpannableStringUtil.java
│ │ │ ├── StatusBar
│ │ │ │ ├── StatusBarUtil.java
│ │ │ │ └── TestStatusBarUtilActivity.java
│ │ │ ├── StringUtil.java
│ │ │ ├── SystemUtil.java
│ │ │ ├── TestUtilActivity.java
│ │ │ ├── ToastUtil.java
│ │ │ ├── TransformUtil.java
│ │ │ ├── VibrationUtil.java
│ │ │ ├── ZipUtil.java
│ │ │ ├── activity
│ │ │ │ ├── ActivityUtil.java
│ │ │ │ └── TestJumpActivity.java
│ │ │ ├── app
│ │ │ │ ├── AATest
│ │ │ │ │ ├── AppAdapter.java
│ │ │ │ │ └── TestAppListActivity.java
│ │ │ │ ├── AppInfo.java
│ │ │ │ └── AppUtil.java
│ │ │ ├── bitmap
│ │ │ │ ├── BitmapUtil.java
│ │ │ │ └── TestBitmapActivity.java
│ │ │ ├── code
│ │ │ │ ├── BarCodeUtil.java
│ │ │ │ ├── QRCodeUtil.java
│ │ │ │ └── TestCodeUtilActivity.java
│ │ │ ├── encrypt
│ │ │ │ ├── AESCBCUtil.java
│ │ │ │ ├── AESUtil.java
│ │ │ │ ├── Base64.java
│ │ │ │ ├── DESCBCUtil.java
│ │ │ │ ├── DESUtil.java
│ │ │ │ ├── MessageDigestUtil.java
│ │ │ │ ├── RSAUtil.java
│ │ │ │ └── SingtureUtil.java
│ │ │ ├── glide
│ │ │ │ ├── GlideUtil.java
│ │ │ │ ├── SectionRoundedCorners.java
│ │ │ │ └── TestGlideActivity.java
│ │ │ ├── location
│ │ │ │ ├── LocationService.java
│ │ │ │ └── LocationUtil.java
│ │ │ ├── permission
│ │ │ │ ├── PermissionUtil.java
│ │ │ │ └── TestPermissionActivity.java
│ │ │ ├── regex
│ │ │ │ ├── RegexConstant.java
│ │ │ │ └── RegexUtil.java
│ │ │ ├── service
│ │ │ │ ├── ServiceUtil.java
│ │ │ │ └── TestService.java
│ │ │ ├── sharedPreferences
│ │ │ │ ├── withContext
│ │ │ │ │ └── SPUtil.java
│ │ │ │ └── withoutContext
│ │ │ │ │ ├── SPUtil.java
│ │ │ │ │ └── SPUtils.java
│ │ │ ├── threadPool
│ │ │ │ ├── AATest
│ │ │ │ │ ├── CalculateTask.java
│ │ │ │ │ └── TestThreadPoolUtilActivity.java
│ │ │ │ ├── StepThread.java
│ │ │ │ ├── ThreadPoolManager.java
│ │ │ │ └── ThreadPoolUtil.java
│ │ │ └── traffic
│ │ │ │ ├── NetworkStatsHelper.java
│ │ │ │ ├── TrafficInfo.java
│ │ │ │ └── TrafficStatsUtil.java
│ │ │ └── widget
│ │ │ ├── ArcView.java
│ │ │ ├── CustomViewPager.java
│ │ │ ├── Dialog
│ │ │ ├── BaseDialog.java
│ │ │ ├── CommonDialog.java
│ │ │ ├── ConfirmDialog.java
│ │ │ └── TestDialogActivity.java
│ │ │ ├── FloatWindow
│ │ │ ├── NeedPermission
│ │ │ │ ├── AATest
│ │ │ │ │ ├── TestFloatPageOneActivity.java
│ │ │ │ │ ├── TestFloatPageThreeActivity.java
│ │ │ │ │ └── TestFloatPageTwoActivity.java
│ │ │ │ ├── FloatActivity.java
│ │ │ │ ├── FloatLifecycle.java
│ │ │ │ ├── FloatPermissionUtil.java
│ │ │ │ ├── FloatWindow.java
│ │ │ │ ├── IFloatWindow.java
│ │ │ │ ├── IFloatWindowImpl.java
│ │ │ │ ├── MoveType.java
│ │ │ │ ├── OnPermissionListener.java
│ │ │ │ ├── OnViewListener.java
│ │ │ │ ├── OnViewStateListener.java
│ │ │ │ ├── ScreenType.java
│ │ │ │ └── compat
│ │ │ │ │ └── MIUI.java
│ │ │ ├── NoPermission
│ │ │ │ ├── AATest
│ │ │ │ │ └── TestFloatPageActivity.java
│ │ │ │ ├── FloatWindow.java
│ │ │ │ ├── IFloatWindow.java
│ │ │ │ ├── MoveType.java
│ │ │ │ ├── OnViewListener.java
│ │ │ │ └── ScreenType.java
│ │ │ └── TestFloatActivity.java
│ │ │ ├── InputLayout.java
│ │ │ ├── LoadingDialog
│ │ │ ├── LoadingDialog.java
│ │ │ └── LoadingView.java
│ │ │ ├── LoadingLayout
│ │ │ ├── LoadingLayout.java
│ │ │ └── TestLoadingLayoutActivity.java
│ │ │ ├── MaxHeightRecyclerView.java
│ │ │ ├── PasswordEditText.java
│ │ │ ├── PhotoViewer
│ │ │ ├── PhotoViewActivity.java
│ │ │ ├── PhotoViewAdapter.java
│ │ │ ├── helper
│ │ │ │ └── CustomGestureDetector.java
│ │ │ ├── listener
│ │ │ │ ├── OnGestureListener.java
│ │ │ │ ├── OnMatrixChangedListener.java
│ │ │ │ ├── OnOutsidePhotoTapListener.java
│ │ │ │ ├── OnPhotoTapListener.java
│ │ │ │ ├── OnScaleChangedListener.java
│ │ │ │ ├── OnSingleFlingListener.java
│ │ │ │ ├── OnViewDragListener.java
│ │ │ │ └── OnViewTapListener.java
│ │ │ └── widget
│ │ │ │ ├── PhotoView.java
│ │ │ │ ├── PhotoViewAttacher.java
│ │ │ │ └── PhotoViewPager.java
│ │ │ ├── PicGetterDialog
│ │ │ ├── AATest
│ │ │ │ ├── CustomPicGetterDialog.java
│ │ │ │ └── TestPicGetterDialogActivity.java
│ │ │ ├── BasePicGetterDialog.java
│ │ │ ├── OnPicGetterListener.java
│ │ │ ├── PicGetterDialog.java
│ │ │ └── 说明.md
│ │ │ ├── PopupWindow
│ │ │ ├── AATest
│ │ │ │ ├── PopupWindowAdapter.java
│ │ │ │ └── TestPopupWindowActivity.java
│ │ │ ├── CommonPopupWindow.java
│ │ │ └── WindowHelper.java
│ │ │ ├── ProgressBar
│ │ │ └── TestProgressBarActivity.java
│ │ │ ├── RecyclerView
│ │ │ ├── AATest
│ │ │ │ ├── TestFooterAdapter.java
│ │ │ │ ├── TestFooterAdapterActivity.java
│ │ │ │ ├── TestHeaderAdapter.java
│ │ │ │ ├── TestHeaderAdapterActivity.java
│ │ │ │ ├── TestLoadMoreWrapper.java
│ │ │ │ ├── TestLoadMoreWrapperActivity.java
│ │ │ │ ├── TestMultiAdapter.java
│ │ │ │ ├── TestMultiAdapterActivity.java
│ │ │ │ ├── TestMultiLoadMoreAdapter.java
│ │ │ │ ├── TestMultiLoadMoreAdapterActivity.java
│ │ │ │ ├── TestRecyclerViewActivity.java
│ │ │ │ ├── TestSingleAdapter.java
│ │ │ │ ├── TestSingleAdapterActivity.java
│ │ │ │ ├── TestSingleLoadMoreAdapter.java
│ │ │ │ ├── TestSingleLoadMoreAdapterActivity.java
│ │ │ │ └── entity
│ │ │ │ │ ├── DateBean.java
│ │ │ │ │ ├── DetailBean.java
│ │ │ │ │ └── MonthBean.java
│ │ │ ├── BaseAdapter.java
│ │ │ ├── LoadMoreAdapter.java
│ │ │ ├── LoadMoreListener.java
│ │ │ ├── LoadMoreWrapper.java
│ │ │ ├── MultiViewType.java
│ │ │ └── ViewHolder.java
│ │ │ ├── ScrollTextView.java
│ │ │ ├── ShadowLayout.java
│ │ │ ├── TestSingleWidgetActivity.java
│ │ │ ├── TitleBar.java
│ │ │ ├── VerifyCodeView.java
│ │ │ ├── ViewHolder.java
│ │ │ └── justtext
│ │ │ ├── AATest
│ │ │ ├── SpanConfigAdapter.java
│ │ │ └── TestJusttextActivity.java
│ │ │ ├── ArrayUtils.java
│ │ │ ├── EmptyArray.java
│ │ │ ├── JustTextView.java
│ │ │ ├── JustUtils.java
│ │ │ ├── SpanConfig.java
│ │ │ ├── SpanSet.java
│ │ │ └── TextLine.java
│ └── res
│ │ ├── layout
│ │ ├── activity_common_layout.xml
│ │ ├── activity_guide.xml
│ │ ├── activity_list_layout.xml
│ │ ├── activity_main.xml
│ │ ├── activity_photo_view.xml
│ │ ├── activity_test_adapter.xml
│ │ ├── activity_test_bitmap.xml
│ │ ├── activity_test_capture_gridview.xml
│ │ ├── activity_test_capture_listview.xml
│ │ ├── activity_test_capture_recyclerview.xml
│ │ ├── activity_test_capture_webview.xml
│ │ ├── activity_test_code_util.xml
│ │ ├── activity_test_fragment.xml
│ │ ├── activity_test_glide.xml
│ │ ├── activity_test_justtext.xml
│ │ ├── activity_test_loading_layout.xml
│ │ ├── activity_test_mvc.xml
│ │ ├── activity_test_mvc_list.xml
│ │ ├── activity_test_pic_getter_dialog.xml
│ │ ├── activity_test_popup_window.xml
│ │ ├── activity_test_progress_bar.xml
│ │ ├── activity_test_single_widget.xml
│ │ ├── activity_weather.xml
│ │ ├── activity_webview.xml
│ │ ├── fragment_frame.xml
│ │ ├── fragment_test_mvc.xml
│ │ ├── fragment_test_mvc_list.xml
│ │ ├── fragment_util.xml
│ │ ├── fragment_webview.xml
│ │ ├── fragment_widget.xml
│ │ ├── item_span_config.xml
│ │ └── view_load_more.xml
│ │ └── values
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── android
│ └── java
│ └── ExampleUnitTest.java
├── kotlin
├── .gitignore
├── build.gradle
├── proguard-rules.pro
├── proguardMapping.txt
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── android
│ │ └── basicproject
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── android
│ │ │ ├── base
│ │ │ ├── BaseApplication.kt
│ │ │ ├── DontSwipeBack.kt
│ │ │ ├── FrameFragment.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── UtilFragment.kt
│ │ │ └── WidgetFragment.kt
│ │ │ ├── frame
│ │ │ ├── TestLeakActivity.kt
│ │ │ ├── camera
│ │ │ │ └── zxing
│ │ │ │ │ ├── AATest
│ │ │ │ │ ├── ScanActivity.kt
│ │ │ │ │ └── TestZXingActivity.kt
│ │ │ │ │ ├── camera
│ │ │ │ │ ├── AutoFocusCallback.java
│ │ │ │ │ ├── CameraConfigurationManager.java
│ │ │ │ │ ├── CameraManager.java
│ │ │ │ │ ├── PlanarYUVLuminanceSource.java
│ │ │ │ │ └── PreviewCallback.java
│ │ │ │ │ ├── decode
│ │ │ │ │ ├── CaptureActivityHandler.java
│ │ │ │ │ ├── DecodeFormatManager.java
│ │ │ │ │ ├── DecodeHandler.java
│ │ │ │ │ ├── DecodeThread.java
│ │ │ │ │ ├── FinishListener.java
│ │ │ │ │ ├── InactivityTimer.java
│ │ │ │ │ ├── Intents.java
│ │ │ │ │ └── RGBLuminanceSource.java
│ │ │ │ │ ├── encode
│ │ │ │ │ └── EncodingHandler.java
│ │ │ │ │ ├── sound
│ │ │ │ │ └── BeepManager.kt
│ │ │ │ │ ├── ui
│ │ │ │ │ └── CaptureActivity.kt
│ │ │ │ │ ├── util
│ │ │ │ │ ├── QRCodeUtil.java
│ │ │ │ │ └── QRConstant.java
│ │ │ │ │ └── view
│ │ │ │ │ ├── ViewfinderResultPointCallback.java
│ │ │ │ │ └── ViewfinderView.java
│ │ │ ├── guide
│ │ │ │ ├── GuideActivity.kt
│ │ │ │ └── SimpleViewAdapter.kt
│ │ │ ├── http
│ │ │ │ ├── AATest
│ │ │ │ │ ├── ApiService.kt
│ │ │ │ │ ├── TestRetrofitActivity.kt
│ │ │ │ │ ├── UrlConstant.kt
│ │ │ │ │ ├── WangYiNewsWebviewActivity.kt
│ │ │ │ │ └── bean
│ │ │ │ │ │ ├── NewsListBean.kt
│ │ │ │ │ │ └── WeatherBean.kt
│ │ │ │ ├── CookieJarManage.kt
│ │ │ │ ├── ExceptionUtil.kt
│ │ │ │ ├── RetrofitFactory.kt
│ │ │ │ ├── SSLSocketFactoryUtil.kt
│ │ │ │ ├── SchedulerUtil.kt
│ │ │ │ ├── function
│ │ │ │ │ └── RetryWithDelay.kt
│ │ │ │ ├── interceptor
│ │ │ │ │ ├── HttpCacheInterceptor.kt
│ │ │ │ │ ├── HttpLogInterceptor.kt
│ │ │ │ │ └── MaxRetryInterceptor.kt
│ │ │ │ └── model
│ │ │ │ │ ├── BaseListResponse.kt
│ │ │ │ │ └── BaseResponse.kt
│ │ │ ├── mvc
│ │ │ │ ├── AATest
│ │ │ │ │ ├── TestActivityMvc.kt
│ │ │ │ │ ├── TestFragmentMvc.kt
│ │ │ │ │ ├── TestMvcActivity.kt
│ │ │ │ │ ├── TestMvcFragment.kt
│ │ │ │ │ ├── TestMvcListActivity.kt
│ │ │ │ │ ├── TestMvcListFragment.kt
│ │ │ │ │ ├── TestWebviewActivity.kt
│ │ │ │ │ ├── adapter
│ │ │ │ │ │ └── NewsListAdapter.kt
│ │ │ │ │ ├── convert
│ │ │ │ │ │ ├── NewsFunction.kt
│ │ │ │ │ │ └── WeatherFunction.kt
│ │ │ │ │ ├── entity
│ │ │ │ │ │ ├── NewsListBean.kt
│ │ │ │ │ │ └── WeatherBean.kt
│ │ │ │ │ └── server
│ │ │ │ │ │ ├── ApiHelper.kt
│ │ │ │ │ │ ├── ApiService.kt
│ │ │ │ │ │ └── Config.kt
│ │ │ │ ├── BaseActivity.kt
│ │ │ │ ├── BaseFragment.kt
│ │ │ │ ├── BaseListActivity.kt
│ │ │ │ ├── BaseListFragment.kt
│ │ │ │ ├── IBaseListView.kt
│ │ │ │ ├── IBaseView.kt
│ │ │ │ ├── ImageInterface.kt
│ │ │ │ ├── WebviewActivity.kt
│ │ │ │ ├── WebviewFragment.kt
│ │ │ │ └── extra
│ │ │ │ │ ├── RecyclerView
│ │ │ │ │ ├── CustomLoadMoreView.kt
│ │ │ │ │ └── LoadMoreAdapter.kt
│ │ │ │ │ └── http
│ │ │ │ │ └── CustomObserver.kt
│ │ │ ├── mvp
│ │ │ │ ├── AATest
│ │ │ │ │ ├── TestActivityMvp.kt
│ │ │ │ │ ├── TestFragmentMvp.kt
│ │ │ │ │ ├── listType
│ │ │ │ │ │ ├── TestMvpListActivity.kt
│ │ │ │ │ │ ├── TestMvpListFragment.kt
│ │ │ │ │ │ ├── TestMvpListModel.kt
│ │ │ │ │ │ ├── TestMvpListPresenter.kt
│ │ │ │ │ │ └── TestMvpListView.kt
│ │ │ │ │ └── notListType
│ │ │ │ │ │ ├── TestMvpActivity.kt
│ │ │ │ │ │ ├── TestMvpFragment.kt
│ │ │ │ │ │ ├── TestMvpModel.kt
│ │ │ │ │ │ ├── TestMvpPresenter.kt
│ │ │ │ │ │ └── TestMvpView.kt
│ │ │ │ ├── BaseActivity.kt
│ │ │ │ ├── BaseFragment.kt
│ │ │ │ ├── BaseListActivity.kt
│ │ │ │ ├── BaseListFragment.kt
│ │ │ │ ├── BaseListPresenter.kt
│ │ │ │ ├── BasePresenter.kt
│ │ │ │ ├── CommonBaseActivity.kt
│ │ │ │ ├── CommonBaseFragment.kt
│ │ │ │ ├── IBaseListView.kt
│ │ │ │ ├── IBaseView.kt
│ │ │ │ ├── extra
│ │ │ │ │ └── http
│ │ │ │ │ │ └── CustomObserver.kt
│ │ │ │ └── 注意点.md
│ │ │ ├── mvvm
│ │ │ │ ├── AATest
│ │ │ │ │ ├── TestActivityMvvm.kt
│ │ │ │ │ ├── TestFragmentMvvm.kt
│ │ │ │ │ ├── convert
│ │ │ │ │ │ ├── CustomRequestBodyConverter.kt
│ │ │ │ │ │ ├── NewsConverterFactory.kt
│ │ │ │ │ │ ├── NewsResponseBodyConverter.kt
│ │ │ │ │ │ ├── WeatherConverterFactory.kt
│ │ │ │ │ │ └── WeatherResponseBodyConverter.kt
│ │ │ │ │ ├── listType
│ │ │ │ │ │ ├── TestMvvmListActivity.kt
│ │ │ │ │ │ ├── TestMvvmListActivityViewModel.kt
│ │ │ │ │ │ ├── TestMvvmListFragment.kt
│ │ │ │ │ │ └── TestMvvmListFragmentViewModel.kt
│ │ │ │ │ ├── notListType
│ │ │ │ │ │ ├── TestMvvmActivity.kt
│ │ │ │ │ │ ├── TestMvvmActivityViewModel.kt
│ │ │ │ │ │ ├── TestMvvmFragment.kt
│ │ │ │ │ │ └── TestMvvmFragmentViewModel.kt
│ │ │ │ │ └── server
│ │ │ │ │ │ ├── ApiHelper.kt
│ │ │ │ │ │ ├── ApiService.kt
│ │ │ │ │ │ └── Config.kt
│ │ │ │ ├── BaseActivity.kt
│ │ │ │ ├── BaseFragment.kt
│ │ │ │ ├── BaseListActivity.kt
│ │ │ │ ├── BaseListFragment.kt
│ │ │ │ ├── BaseListViewModel.kt
│ │ │ │ ├── BaseViewModel.kt
│ │ │ │ ├── BaseViewModelWithData.kt
│ │ │ │ ├── CommonBaseActivity.kt
│ │ │ │ ├── CommonBaseFragment.kt
│ │ │ │ ├── IBaseListView.kt
│ │ │ │ ├── IBaseView.kt
│ │ │ │ └── extra
│ │ │ │ │ └── LiveDataEntity
│ │ │ │ │ ├── DialogConfig.kt
│ │ │ │ │ └── ErrorResponse.kt
│ │ │ └── permission
│ │ │ │ ├── PermissionFrameActivity.kt
│ │ │ │ └── PermissionRequestActivity.kt
│ │ │ ├── util
│ │ │ ├── AlertDialogUtil.kt
│ │ │ ├── ApkDownloadUtil.kt
│ │ │ ├── AudioUtil.kt
│ │ │ ├── BrightnessUtil.kt
│ │ │ ├── ByteUnit.kt
│ │ │ ├── CPUUtil.kt
│ │ │ ├── CacheUtil.kt
│ │ │ ├── CapturePicture
│ │ │ │ ├── CapturePictureUtil.kt
│ │ │ │ ├── TestCaptureGridViewActivity.kt
│ │ │ │ ├── TestCaptureListViewActivity.kt
│ │ │ │ ├── TestCaptureRecyclerViewActivity.kt
│ │ │ │ └── TestCaptureWebViewActivity.kt
│ │ │ ├── CheckFastClickUtil.kt
│ │ │ ├── CleanUtil.kt
│ │ │ ├── CommonLayoutUtil.kt
│ │ │ ├── CrashHandler.kt
│ │ │ ├── DataDueUtil.kt
│ │ │ ├── DateUtil.kt
│ │ │ ├── DeviceUtil.kt
│ │ │ ├── DigitalUtil.kt
│ │ │ ├── DrawableUtil.kt
│ │ │ ├── EncodeUtil.kt
│ │ │ ├── ExtraUtil.kt
│ │ │ ├── FileUtil.kt
│ │ │ ├── IOUtil.kt
│ │ │ ├── IntentUtil.kt
│ │ │ ├── JsonUtil.kt
│ │ │ ├── KeyboardUtil.kt
│ │ │ ├── LayoutParamsUtil.kt
│ │ │ ├── LogUtil.kt
│ │ │ ├── NetReceiver.kt
│ │ │ ├── NetworkUtil.kt
│ │ │ ├── NotificationUtil.kt
│ │ │ ├── OnAppBarStateChangeListener.kt
│ │ │ ├── OnMultiClickListener.kt
│ │ │ ├── PhoneUtil.kt
│ │ │ ├── PickerViewUtil.kt
│ │ │ ├── PinyinUtil.kt
│ │ │ ├── SDCardUtil.kt
│ │ │ ├── SPUtil.kt
│ │ │ ├── ScreenUtil.kt
│ │ │ ├── ShellUtil.kt
│ │ │ ├── SizeUtil.kt
│ │ │ ├── StatusBar
│ │ │ │ ├── StatusBarUtil.kt
│ │ │ │ └── TestStatusBarUtilActivity.kt
│ │ │ ├── StringUtil.kt
│ │ │ ├── TestUtilActivity.kt
│ │ │ ├── ToastUtil.kt
│ │ │ ├── TransformUtil.kt
│ │ │ ├── VibrationUtil.kt
│ │ │ ├── ViewExt.kt
│ │ │ ├── ZipUtil.kt
│ │ │ ├── activity
│ │ │ │ ├── ActivityUtil.kt
│ │ │ │ └── TestJumpActivity.kt
│ │ │ ├── app
│ │ │ │ ├── AATest
│ │ │ │ │ ├── AppAdapter.kt
│ │ │ │ │ └── TestAppListActivity.kt
│ │ │ │ ├── AppInfo.kt
│ │ │ │ └── AppUtil.kt
│ │ │ ├── bitmap
│ │ │ │ ├── BitmapUtil.kt
│ │ │ │ └── TestBitmapActivity.kt
│ │ │ ├── code
│ │ │ │ ├── BarCodeUtil.kt
│ │ │ │ ├── QRCodeUtil.kt
│ │ │ │ └── TestCodeUtilActivity.kt
│ │ │ ├── encrypt
│ │ │ │ ├── AESCBCUtil.kt
│ │ │ │ ├── AESUtil.kt
│ │ │ │ ├── Base64.kt
│ │ │ │ ├── DESCBCUtil.kt
│ │ │ │ ├── DESUtil.kt
│ │ │ │ ├── MessageDigestUtil.kt
│ │ │ │ ├── RSAUtil.kt
│ │ │ │ └── SingtureUtil.kt
│ │ │ ├── glide
│ │ │ │ ├── GlideUtil.kt
│ │ │ │ ├── SectionRoundedCorners.kt
│ │ │ │ └── TestGlideActivity.kt
│ │ │ ├── location
│ │ │ │ ├── LocationService.kt
│ │ │ │ └── LocationUtil.kt
│ │ │ ├── permission
│ │ │ │ ├── PermissionUtil.kt
│ │ │ │ └── TestPermissionActivity.kt
│ │ │ ├── regex
│ │ │ │ ├── RegexConstant.kt
│ │ │ │ └── RegexUtil.kt
│ │ │ ├── service
│ │ │ │ ├── ServiceUtil.kt
│ │ │ │ └── TestService.kt
│ │ │ └── threadPool
│ │ │ │ ├── AATest
│ │ │ │ ├── CalculateTask.kt
│ │ │ │ └── TestThreadPoolUtilActivity.kt
│ │ │ │ ├── StepThread.kt
│ │ │ │ ├── ThreadPoolManager.kt
│ │ │ │ └── ThreadPoolUtil.kt
│ │ │ └── widget
│ │ │ ├── ArcView.kt
│ │ │ ├── CustomViewPager.kt
│ │ │ ├── DashLine.kt
│ │ │ ├── ExpandTextView
│ │ │ ├── BoldInfo.kt
│ │ │ ├── ColorInfo.kt
│ │ │ └── ExpandTextView.kt
│ │ │ ├── FloatWindow
│ │ │ ├── NeedPermission
│ │ │ │ ├── AATest
│ │ │ │ │ ├── TestFloatPageOneActivity.kt
│ │ │ │ │ ├── TestFloatPageThreeActivity.kt
│ │ │ │ │ └── TestFloatPageTwoActivity.kt
│ │ │ │ ├── FloatActivity.kt
│ │ │ │ ├── FloatLifecycle.kt
│ │ │ │ ├── FloatPermissionUtil.kt
│ │ │ │ ├── FloatWindow.kt
│ │ │ │ ├── IFloatWindow.kt
│ │ │ │ ├── IFloatWindowImpl.kt
│ │ │ │ ├── MoveType.kt
│ │ │ │ ├── OnPermissionListener.kt
│ │ │ │ ├── OnViewStateListener.kt
│ │ │ │ ├── ScreenType.kt
│ │ │ │ └── compat
│ │ │ │ │ └── MIUI.kt
│ │ │ ├── NoPermission
│ │ │ │ ├── AATest
│ │ │ │ │ └── TestFloatPageActivity.kt
│ │ │ │ ├── FloatWindow.kt
│ │ │ │ ├── IFloatWindow.kt
│ │ │ │ ├── MoveType.kt
│ │ │ │ └── ScreenType.kt
│ │ │ └── TestFloatActivity.kt
│ │ │ ├── IndicatorLayout.kt
│ │ │ ├── InputLayout.kt
│ │ │ ├── LetterIndexBar
│ │ │ ├── BubbleLetterIndexBar.kt
│ │ │ ├── LetterIndexBar.kt
│ │ │ └── TestLetterIndexBarActivity.kt
│ │ │ ├── LineChart
│ │ │ ├── TestLineChartActivity.kt
│ │ │ ├── type1
│ │ │ │ └── LineChart.kt
│ │ │ └── type2
│ │ │ │ └── LineChart.kt
│ │ │ ├── LoadingDialog
│ │ │ ├── LoadingDialog.kt
│ │ │ └── LoadingView.kt
│ │ │ ├── LoadingLayout
│ │ │ ├── LoadingLayout.kt
│ │ │ └── TestLoadingLayoutActivity.kt
│ │ │ ├── MaxHeightRecyclerView.kt
│ │ │ ├── NestedWebView.kt
│ │ │ ├── PasswordEditText.kt
│ │ │ ├── PhotoViewer
│ │ │ ├── PhotoViewActivity.kt
│ │ │ ├── PhotoViewAdapter.kt
│ │ │ ├── helper
│ │ │ │ └── CustomGestureDetector.kt
│ │ │ ├── listener
│ │ │ │ ├── OnGestureListener.kt
│ │ │ │ ├── OnMatrixChangedListener.kt
│ │ │ │ ├── OnOutsidePhotoTapListener.kt
│ │ │ │ ├── OnPhotoTapListener.kt
│ │ │ │ ├── OnScaleChangedListener.kt
│ │ │ │ ├── OnSingleFlingListener.kt
│ │ │ │ ├── OnViewDragListener.kt
│ │ │ │ └── OnViewTapListener.kt
│ │ │ └── widget
│ │ │ │ ├── PhotoView.kt
│ │ │ │ ├── PhotoViewAttacher.kt
│ │ │ │ └── PhotoViewPager.kt
│ │ │ ├── PicGetterDialog
│ │ │ ├── AATest
│ │ │ │ ├── CustomPicGetterDialog.kt
│ │ │ │ └── TestPicGetterDialogActivity.kt
│ │ │ ├── BasePicGetterDialog.kt
│ │ │ ├── OnPicGetterListener.kt
│ │ │ ├── PicGetterDialog.kt
│ │ │ └── 说明.md
│ │ │ ├── PieChart
│ │ │ ├── PieData.kt
│ │ │ ├── TestPieChartActivity.kt
│ │ │ ├── type1
│ │ │ │ └── PieChart.kt
│ │ │ └── type2
│ │ │ │ └── PieChart.kt
│ │ │ ├── PopupWindow
│ │ │ ├── AATest
│ │ │ │ ├── PopupWindowAdapter.kt
│ │ │ │ └── TestPopupWindowActivity.kt
│ │ │ ├── CommonPopupWindow.kt
│ │ │ └── WindowHelper.kt
│ │ │ ├── ProgressBar
│ │ │ ├── CircleProgressBar.kt
│ │ │ └── TestProgressBarActivity.kt
│ │ │ ├── RecyclerView
│ │ │ ├── AATest
│ │ │ │ ├── TestFooterAdapter.kt
│ │ │ │ ├── TestFooterAdapterActivity.kt
│ │ │ │ ├── TestHeaderAdapter.kt
│ │ │ │ ├── TestHeaderAdapterActivity.kt
│ │ │ │ ├── TestLoadMoreWrapper.kt
│ │ │ │ ├── TestLoadMoreWrapperActivity.kt
│ │ │ │ ├── TestMultiAdapter.kt
│ │ │ │ ├── TestMultiAdapterActivity.kt
│ │ │ │ ├── TestMultiLoadMoreAdapter.kt
│ │ │ │ ├── TestMultiLoadMoreAdapterActivity.kt
│ │ │ │ ├── TestRecyclerViewActivity.kt
│ │ │ │ ├── TestSingleAdapter.kt
│ │ │ │ ├── TestSingleAdapterActivity.kt
│ │ │ │ ├── TestSingleLoadMoreAdapter.kt
│ │ │ │ ├── TestSingleLoadMoreAdapterActivity.kt
│ │ │ │ └── entity
│ │ │ │ │ ├── DateBean.kt
│ │ │ │ │ ├── DetailBean.kt
│ │ │ │ │ └── MonthBean.kt
│ │ │ ├── BaseAdapter.kt
│ │ │ ├── LoadMoreAdapter.kt
│ │ │ ├── LoadMoreListener.kt
│ │ │ ├── LoadMoreWrapper.kt
│ │ │ ├── MultiViewType.kt
│ │ │ └── ViewHolder.kt
│ │ │ ├── RoundImageView.kt
│ │ │ ├── ScrollTextView.kt
│ │ │ ├── SearchLayout.kt
│ │ │ ├── SuffixTextView.kt
│ │ │ ├── TestSingleWidgetActivity.kt
│ │ │ ├── TitleBar.kt
│ │ │ ├── VerificationCodeEditText.kt
│ │ │ ├── ViewHolder.kt
│ │ │ └── dialog
│ │ │ ├── BaseDialog.kt
│ │ │ ├── CommonDialog.kt
│ │ │ ├── ConfirmDialog.kt
│ │ │ └── TestDialogActivity.kt
│ └── res
│ │ ├── layout
│ │ ├── activity_capture.xml
│ │ ├── activity_common_layout.xml
│ │ ├── activity_guide.xml
│ │ ├── activity_list_layout.xml
│ │ ├── activity_main.xml
│ │ ├── activity_photo_view.xml
│ │ ├── activity_scan.xml
│ │ ├── activity_test_adapter.xml
│ │ ├── activity_test_bitmap.xml
│ │ ├── activity_test_capture_gridview.xml
│ │ ├── activity_test_capture_listview.xml
│ │ ├── activity_test_capture_recyclerview.xml
│ │ ├── activity_test_capture_webview.xml
│ │ ├── activity_test_code_util.xml
│ │ ├── activity_test_fragment.xml
│ │ ├── activity_test_glide.xml
│ │ ├── activity_test_letter_index_bar.xml
│ │ ├── activity_test_line_chart.xml
│ │ ├── activity_test_loading_layout.xml
│ │ ├── activity_test_mvc.xml
│ │ ├── activity_test_mvc_list.xml
│ │ ├── activity_test_pic_getter_dialog.xml
│ │ ├── activity_test_pie_chart.xml
│ │ ├── activity_test_popup_window.xml
│ │ ├── activity_test_progress_bar.xml
│ │ ├── activity_test_single_widget.xml
│ │ ├── activity_weather.xml
│ │ ├── activity_webview.xml
│ │ ├── fragment_frame.xml
│ │ ├── fragment_test_mvc.xml
│ │ ├── fragment_test_mvc_list.xml
│ │ ├── fragment_util.xml
│ │ ├── fragment_webview.xml
│ │ ├── fragment_widget.xml
│ │ └── view_load_more.xml
│ │ └── values
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── android
│ └── basicproject
│ └── ExampleUnitTest.kt
├── settings.gradle
└── universal
├── .gitignore
├── BasicProject.jks
├── build.gradle
├── proguard-rules.pro
└── src
├── androidTest
└── java
│ └── com
│ └── android
│ └── universal
│ └── ExampleInstrumentedTest.java
├── main
├── AndroidManifest.xml
├── assets
│ ├── fonts
│ │ └── fonts.ttf
│ └── test_install.apk
├── java
│ └── com
│ │ └── android
│ │ └── universal
│ │ ├── TestSystemWidgetActivity.kt
│ │ └── TestSystemWidgetFragment.kt
└── res
│ ├── anim
│ ├── alpha_in_150.xml
│ ├── alpha_in_300.xml
│ ├── alpha_out_150.xml
│ ├── alpha_out_300.xml
│ ├── scale_bottom_in.xml
│ ├── scale_bottom_out.xml
│ ├── scale_center_in.xml
│ ├── scale_center_out.xml
│ ├── scale_left_in.xml
│ ├── scale_left_out.xml
│ ├── scale_right_in.xml
│ ├── scale_right_out.xml
│ ├── scale_top_in.xml
│ ├── scale_top_out.xml
│ ├── slide_left_in.xml
│ ├── slide_left_out.xml
│ ├── slide_right_in.xml
│ ├── slide_right_out.xml
│ ├── translate_bottom_in.xml
│ ├── translate_bottom_out.xml
│ ├── translate_left_in.xml
│ ├── translate_left_out.xml
│ ├── translate_right_in.xml
│ ├── translate_right_out.xml
│ ├── translate_top_in.xml
│ └── translate_top_out.xml
│ ├── color
│ ├── selector_tab_text_color.xml
│ └── selector_toggle_button_text_color.xml
│ ├── drawable-xhdpi
│ ├── ic_add.png
│ ├── ic_back.png
│ ├── ic_bg.png
│ ├── ic_bitmap.jpg
│ ├── ic_check.png
│ ├── ic_clear.png
│ ├── ic_coupon_btn.png
│ ├── ic_coupon_header.png
│ ├── ic_empty_data.png
│ ├── ic_face1.png
│ ├── ic_face2.png
│ ├── ic_face3.png
│ ├── ic_flashlight_off.png
│ ├── ic_flashlight_on.png
│ ├── ic_frame_not_selected.png
│ ├── ic_frame_selected.png
│ ├── ic_guide_bg.png
│ ├── ic_guide_one.png
│ ├── ic_guide_three.png
│ ├── ic_guide_two.png
│ ├── ic_letter_bubble.png
│ ├── ic_load_empty.png
│ ├── ic_load_fail.png
│ ├── ic_load_loading.png
│ ├── ic_more.png
│ ├── ic_msg.png
│ ├── ic_photo_close.png
│ ├── ic_photo_download.png
│ ├── ic_photo_load_fail.png
│ ├── ic_qq.png
│ ├── ic_query.png
│ ├── ic_scan_grid.png
│ ├── ic_search_clear.png
│ ├── ic_search_search.png
│ ├── ic_settings.png
│ ├── ic_status_bar.jpeg
│ ├── ic_uncheck.png
│ ├── ic_util_not_selected.png
│ ├── ic_util_selected.png
│ ├── ic_warn.png
│ ├── ic_weibo.png
│ ├── ic_weixin.png
│ ├── ic_widget_not_selected.png
│ └── ic_widget_selected.png
│ ├── drawable
│ ├── layer_list_bg.xml
│ ├── layer_list_input_layout.xml
│ ├── layer_list_progress_drawable.xml
│ ├── layer_list_shadow_bg1.xml
│ ├── layer_list_shadow_bg2.xml
│ ├── loading_progressbar_bg.xml
│ ├── selector_bottom_frame.xml
│ ├── selector_bottom_util.xml
│ ├── selector_bottom_widget.xml
│ ├── selector_btn_bg.xml
│ ├── selector_flash_light_switch.xml
│ ├── selector_gray_item_layout_bg.xml
│ ├── selector_guide_indicator.xml
│ ├── selector_guide_use_btn_bg.xml
│ ├── selector_item_check_btn.xml
│ ├── selector_item_layout_bg.xml
│ ├── selector_tab_text_color.xml
│ ├── selector_toggle_button_bg.xml
│ ├── shape_confirm_dialog.xml
│ ├── shape_corners_10_solid_000000.xml
│ ├── shape_corners_15_solid_ffffff.xml
│ ├── shape_corners_15_solid_transparent.xml
│ ├── shape_corners_17_solid_66000000.xml
│ ├── shape_coupon_dialog.xml
│ ├── shape_cursor_drawable.xml
│ ├── shape_indicator_bg.xml
│ ├── shape_loading_btn_bg.xml
│ ├── shape_loading_dialog_bg.xml
│ ├── shape_oval_size_34_solid_66000000.xml
│ ├── shape_oval_size_34_solid_db4b3c.xml
│ ├── shape_photo_view_progress_bg.xml
│ ├── shape_progressbar_bg.xml
│ ├── shape_progressbar_progress.xml
│ ├── shape_search_layout.xml
│ ├── shape_size_2_solid_0071ff.xml
│ └── shape_spannable_block.xml
│ ├── layout
│ ├── activity_test_system_widget.xml
│ ├── dialog_app_detail.xml
│ ├── dialog_confirm.xml
│ ├── dialog_custom_pic_getter.xml
│ ├── dialog_loading.xml
│ ├── dialog_loading_layout.xml
│ ├── dialog_pic_getter.xml
│ ├── fragment_test_system_widget1.xml
│ ├── fragment_test_system_widget2.xml
│ ├── fragment_test_system_widget3.xml
│ ├── fragment_test_system_widget4.xml
│ ├── fragment_test_system_widget5.xml
│ ├── fragment_test_system_widget6.xml
│ ├── fragment_test_system_widget7.xml
│ ├── fragment_test_system_widget8.xml
│ ├── item_detail.xml
│ ├── item_header.xml
│ ├── item_image_with_text.xml
│ ├── item_month.xml
│ ├── item_photo_view_pager.xml
│ ├── item_popup_window.xml
│ ├── item_test_capture.xml
│ ├── item_test_load_more.xml
│ ├── item_text_with_checkbox.xml
│ ├── item_text_with_image.xml
│ ├── layout_comment_dialog.xml
│ ├── layout_coupon_dialog.xml
│ ├── layout_empty_view.xml
│ ├── layout_float.xml
│ ├── layout_guide_one.xml
│ ├── layout_guide_three.xml
│ ├── layout_guide_two.xml
│ ├── layout_image.xml
│ ├── layout_input.xml
│ ├── layout_loading.xml
│ ├── layout_net_error.xml
│ ├── layout_popup_window_full.xml
│ ├── layout_popup_window_to_bottom1.xml
│ ├── layout_popup_window_to_bottom2.xml
│ ├── layout_popup_window_to_left_or_right.xml
│ ├── layout_popup_window_to_top.xml
│ ├── layout_recycler_view.xml
│ ├── layout_refresh_footer.xml
│ ├── layout_search.xml
│ ├── layout_share_dialog.xml
│ ├── layout_tab_content.xml
│ ├── layout_title_bar.xml
│ └── layout_toast.xml
│ ├── mipmap-hdpi
│ └── ic_logo.png
│ ├── mipmap-mdpi
│ └── ic_logo.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_logo.png
│ ├── mipmap-xxhdpi
│ └── ic_logo.png
│ ├── mipmap-xxxhdpi
│ └── ic_logo.png
│ ├── raw
│ ├── beep.mp3
│ ├── hex_alpha_table
│ └── notification.mp3
│ ├── values
│ ├── arrays.xml
│ ├── attrs.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── ids.xml
│ ├── strings.xml
│ └── styles.xml
│ └── xml
│ ├── network_security_config.xml
│ └── provider_paths.xml
└── test
└── java
└── com
└── android
└── universal
└── ExampleUnitTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | /.idea/*
3 | .gradle
4 | /local.properties
5 | .DS_Store
6 | /build
7 | /captures
8 | .externalNativeBuild
9 |
--------------------------------------------------------------------------------
/apk/Java_release_v1.0.0(002).apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/apk/Java_release_v1.0.0(002).apk
--------------------------------------------------------------------------------
/apk/Kotlin_release_v1.0.0(001).apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/apk/Kotlin_release_v1.0.0(001).apk
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # Kotlin code style for this project: "official" or "obsolete":
15 | kotlin.code.style=official
16 | android.useAndroidX=true
17 | android.enableJetifier=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Oct 19 16:21:05 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip
7 |
--------------------------------------------------------------------------------
/java/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/java/src/androidTest/java/com/android/java/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.android.java;
2 |
3 | import android.content.Context;
4 | import androidx.test.platform.app.InstrumentationRegistry;
5 | import androidx.test.ext.junit.runners.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.android.java.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/base/DontSwipeBack.java:
--------------------------------------------------------------------------------
1 | package com.android.base;
2 |
3 | /**
4 | * Created by xuzhb on 2020/12/30
5 | * Desc:不需要侧滑退出Activity
6 | */
7 | public interface DontSwipeBack {
8 | }
9 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/TestLeakActivity.java:
--------------------------------------------------------------------------------
1 | package com.android.frame;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 |
6 | import com.android.frame.mvc.BaseActivity;
7 | import com.android.java.R;
8 | import com.android.java.databinding.ActivityCommonLayoutBinding;
9 | import com.android.util.CommonLayoutUtil;
10 |
11 | /**
12 | * Created by xuzhb on 2019/11/2
13 | * Desc:测试内存泄漏
14 | */
15 | public class TestLeakActivity extends BaseActivity {
16 |
17 | private static Context mContext;
18 |
19 | @Override
20 | public void handleView(Bundle savedInstanceState) {
21 | CommonLayoutUtil.initCommonLayout(this, "测试内存泄漏");
22 | mContext = this; //测试内存泄漏
23 | }
24 |
25 | @Override
26 | public void initListener() {
27 |
28 | }
29 |
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/http/AATest/UrlConstant.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.http.AATest;
2 |
3 | /**
4 | * Created by xuzhb on 2019/10/26
5 | * Desc:
6 | */
7 | public class UrlConstant {
8 |
9 | public static final String BAIDU_URL = "https://www.baidu.com/";
10 |
11 | public static final String WEATHER_URL = "http://wthrcdn.etouch.cn/";
12 |
13 | public static final String NEWS_URL = "https://api.apiopen.top/";
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/http/SchedulerUtil.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.http;
2 |
3 | import io.reactivex.Observable;
4 | import io.reactivex.ObservableSource;
5 | import io.reactivex.ObservableTransformer;
6 | import io.reactivex.android.schedulers.AndroidSchedulers;
7 | import io.reactivex.schedulers.Schedulers;
8 |
9 | /**
10 | * Created by xuzhb on 2019/10/26
11 | * Desc:简化subscribeOn和observeOn调用
12 | */
13 | public class SchedulerUtil {
14 |
15 | public static ObservableTransformer ioToMain() {
16 | return new ObservableTransformer() {
17 | @Override
18 | public ObservableSource apply(Observable upstream) {
19 | return upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
20 | }
21 | };
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/http/converter/说明.md:
--------------------------------------------------------------------------------
1 | # 自定义GsonConverter解决服务器返回数据格式不一致问题
2 | 参考:
3 | https://blog.csdn.net/Z_DingHao/article/details/78602950
4 | https://blog.csdn.net/u010386612/article/details/67637695
5 | https://blog.csdn.net/w525721508/article/details/78018207
6 | ## GsonConverterFactory转换原理
7 | 相关的三个类:
8 | GsonConverterFactory
9 | GsonRequestBodyConverter:POST请求时将请求的实体转转化成Json
10 | GsonResponseBodyConverter:接收服务器返回数据时将Json转化成对应的实体
11 | 重写GsonResponseBodyConverter转换逻辑即可
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/http/model/BaseResponse.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.http.model;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by xuzhb on 2019/10/26
7 | * Desc:bean基类,非列表类型
8 | */
9 | public class BaseResponse implements Serializable {
10 |
11 | private int code;
12 | private String msg;
13 | private T data;
14 |
15 | public int getCode() {
16 | return code;
17 | }
18 |
19 | public void setCode(int code) {
20 | this.code = code;
21 | }
22 |
23 | public String getMsg() {
24 | return msg;
25 | }
26 |
27 | public void setMsg(String msg) {
28 | this.msg = msg;
29 | }
30 |
31 | public T getData() {
32 | return data;
33 | }
34 |
35 | public void setData(T data) {
36 | this.data = data;
37 | }
38 |
39 | public boolean isSuccess() {
40 | return this.code == 200;
41 | }
42 |
43 | public boolean isTokenOut() { //登录失效
44 | return this.code == -111; //这里假设code是-111
45 | }
46 |
47 | public String getMessage() {
48 | return msg;
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvc/AATest/entity/NewsListBean.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc.AATest.entity;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by xuzhb on 2021/1/1
7 | * Desc:
8 | */
9 | public class NewsListBean implements Serializable {
10 |
11 | private String path;
12 | private String image;
13 | private String title;
14 | private String passtime;
15 |
16 | public String getPath() {
17 | return path;
18 | }
19 |
20 | public void setPath(String path) {
21 | this.path = path;
22 | }
23 |
24 | public String getImage() {
25 | return image;
26 | }
27 |
28 | public void setImage(String image) {
29 | this.image = image;
30 | }
31 |
32 | public String getTitle() {
33 | return title;
34 | }
35 |
36 | public void setTitle(String title) {
37 | this.title = title;
38 | }
39 |
40 | public String getPasstime() {
41 | return passtime;
42 | }
43 |
44 | public void setPasstime(String passtime) {
45 | this.passtime = passtime;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvc/AATest/server/ApiService.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc.AATest.server;
2 |
3 | import io.reactivex.Observable;
4 | import okhttp3.ResponseBody;
5 | import retrofit2.http.Field;
6 | import retrofit2.http.FormUrlEncoded;
7 | import retrofit2.http.GET;
8 | import retrofit2.http.POST;
9 | import retrofit2.http.Query;
10 |
11 | /**
12 | * Created by xuzhb on 2021/1/1
13 | * Desc:
14 | */
15 | public interface ApiService {
16 |
17 | //获取天气信息,@Query,GET请求
18 | @GET("weather_mini")
19 | Observable getWeatherByQuery(@Query("city") String city);
20 |
21 | //获取网易新闻,@Field,POST请求
22 | @FormUrlEncoded
23 | @POST("getWangYiNews")
24 | Observable getWangYiNewsByField(@Field("page") int page, @Field("count") int count);
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvc/AATest/server/Config.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc.AATest.server;
2 |
3 | /**
4 | * Created by xuzhb on 2021/1/1
5 | * Desc:
6 | */
7 | public class Config {
8 |
9 | public static final String WEATHER_URL = "http://wthrcdn.etouch.cn/";
10 |
11 | public static final String NEWS_URL = "https://api.apiopen.top/";
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvc/IBaseListView.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by xuzhb on 2021/8/13
7 | */
8 | public interface IBaseListView extends IBaseView {
9 |
10 | /**
11 | * 获取加载的起始页码
12 | */
13 | int getFirstPage();
14 |
15 | /**
16 | * 是否是首次加载
17 | */
18 | boolean isFirstLoad();
19 |
20 | /**
21 | * 获取一页加载的个数
22 | */
23 | int getLoadSize();
24 |
25 | /**
26 | * 显示数据
27 | */
28 | void showData(int page, List list);
29 |
30 | /**
31 | * 处理数据
32 | */
33 | List convertData(List response);
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvc/extra/RecyclerView/LoadMoreAdapter.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc.extra.RecyclerView;
2 |
3 | import com.chad.library.adapter.base.BaseQuickAdapter;
4 | import com.chad.library.adapter.base.module.LoadMoreModule;
5 | import com.chad.library.adapter.base.viewholder.BaseViewHolder;
6 |
7 | import org.jetbrains.annotations.Nullable;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * Created by xuzhb on 2020/12/31
13 | * Desc:上拉加载更多
14 | */
15 | public abstract class LoadMoreAdapter extends BaseQuickAdapter implements LoadMoreModule {
16 |
17 | public LoadMoreAdapter(int layoutResId) {
18 | super(layoutResId);
19 | }
20 |
21 | public LoadMoreAdapter(int layoutResId, @Nullable List data) {
22 | super(layoutResId, data);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvp/AATest/listType/TestMvpListView.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp.AATest.listType;
2 |
3 | import com.android.frame.mvc.AATest.entity.NewsListBean;
4 | import com.android.frame.mvp.IBaseListView;
5 |
6 | /**
7 | * Created by xuzhb on 2021/1/4
8 | * Desc:
9 | */
10 | public interface TestMvpListView extends IBaseListView {
11 | }
12 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvp/AATest/notListType/TestMvpModel.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp.AATest.notListType;
2 |
3 | import com.android.frame.http.RetrofitFactory;
4 | import com.android.frame.http.SchedulerUtil;
5 | import com.android.frame.http.model.BaseResponse;
6 | import com.android.frame.mvc.AATest.convert.WeatherFunction;
7 | import com.android.frame.mvc.AATest.entity.WeatherBean;
8 | import com.android.frame.mvc.AATest.server.ApiService;
9 | import com.android.frame.mvc.AATest.server.Config;
10 |
11 | import java.util.concurrent.TimeUnit;
12 |
13 | import io.reactivex.Observable;
14 |
15 | /**
16 | * Created by xuzhb on 2021/1/4
17 | * Desc:
18 | */
19 | public class TestMvpModel {
20 |
21 | public Observable> getWeatherInfo(String city) {
22 | return RetrofitFactory.getInstance().createService(ApiService.class, Config.WEATHER_URL, true)
23 | .getWeatherByQuery(city)
24 | .delay(1, TimeUnit.SECONDS) //模拟延迟一段时间后请求到数据的情况
25 | .map(new WeatherFunction())
26 | .compose(SchedulerUtil.ioToMain());
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvp/AATest/notListType/TestMvpView.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp.AATest.notListType;
2 |
3 | import com.android.frame.mvc.AATest.entity.WeatherBean;
4 | import com.android.frame.mvp.IBaseView;
5 |
6 | /**
7 | * Created by xuzhb on 2021/1/4
8 | * Desc:
9 | */
10 | public interface TestMvpView extends IBaseView {
11 |
12 | void showWeatherInfo(String city, WeatherBean bean);
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvp/BasePresenter.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp;
2 |
3 | /**
4 | * Created by xuzhb on 2020/1/5
5 | * Desc:MVP中的基类Presenter
6 | */
7 | public class BasePresenter {
8 |
9 | protected V mView;
10 |
11 | //绑定View
12 | public void attachView(V view) {
13 | this.mView = view;
14 | }
15 |
16 | //解绑View
17 | public void detachView() {
18 | this.mView = null;
19 | }
20 |
21 | public boolean isAttach() {
22 | return mView != null;
23 | }
24 |
25 | //加载数据,进入页面时默认就会进行加载,请务必重写refreshData,当加载失败点击重试或者下拉刷新时会调用这个方法
26 | public void refreshData() {
27 |
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvp/CommonBaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp;
2 |
3 | import androidx.viewbinding.ViewBinding;
4 |
5 | /**
6 | * Created by xuzhb on 2020/1/8
7 | * Desc:不需要额外声明View和Presenter的Activity的父类
8 | */
9 | public abstract class CommonBaseActivity extends BaseActivity> implements IBaseView {
10 |
11 | @Override
12 | public BasePresenter getPresenter() {
13 | return new BasePresenter<>();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvp/CommonBaseFragment.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp;
2 |
3 | import androidx.viewbinding.ViewBinding;
4 |
5 | /**
6 | * Created by xuzhb on 2020/1/8
7 | * Desc:不需要额外声明View和Presenter的Fragment的父类
8 | */
9 | public abstract class CommonBaseFragment extends BaseFragment> implements IBaseView {
10 |
11 | @Override
12 | public BasePresenter getPresenter() {
13 | return new BasePresenter<>();
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvp/IBaseListView.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by xuzhb on 2020/7/22
7 | * Desc:列表数据对应的基类View
8 | */
9 | public interface IBaseListView extends IBaseView {
10 |
11 | /**
12 | * 获取当前加载的页码
13 | */
14 | int getCurrentPage();
15 |
16 | /**
17 | * 设置当前加载的页码
18 | */
19 | void setCurrentPage(int page);
20 |
21 | /**
22 | * 获取加载的起始页码
23 | */
24 | int getFirstPage();
25 |
26 | /**
27 | * 是否是首次加载
28 | */
29 | boolean isFirstLoad();
30 |
31 | /**
32 | * 获取一页加载的个数
33 | */
34 | int getLoadSize();
35 |
36 | /**
37 | * 显示数据
38 | */
39 | void showData(int page, List list);
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvp/注意点.md:
--------------------------------------------------------------------------------
1 | BaseCompatActivity:基类Activity
2 | BaseFragment:基类Fragment
3 | IBaseView:基类View
4 | BasePresenter:基类Presenter
5 | CommonBaseActivity:不需要额外声明View和Presenter的Activity父类
6 | CommonBaseFragment:不需要额外声明View和Presenter的Fragment父类
7 | LoadingDialog:自定义加载框
8 | CustomObserver:自定义Observer,加入加载框和网络错误的处理
9 | NetReceiver:广播监听网络变化,动态注册
10 | activity_list_layout:通用的列表布局,包括标题栏和layout_net_error和layout_recycler_view
11 | layout_net_error:网络错误提示布局
12 | layout_recycler_view:通用的列表刷新子布局,包括一个SwipeRefreshLayout和一个RecyclerView
13 |
14 | 集成时注意:
15 | 1、实现BaseCompatActivity和BaseFragment的gotoLogin()方法
16 | 2、处理CustomObserver中登录失效的code,目前暂定登录过期的code是-1001
17 | 3、处理基类Bean,即BaseResponse和BaseListResponse的结构
18 | 4、处理基类Bean接口请求成功的code,目前暂定接口请求成功的code是200
19 |
20 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvvm/AATest/listType/TestMvvmListFragmentViewModel.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm.AATest.listType;
2 |
3 | import com.android.frame.mvc.AATest.entity.NewsListBean;
4 | import com.android.frame.mvvm.AATest.server.ApiHelper;
5 | import com.android.frame.mvvm.BaseListViewModel;
6 |
7 | /**
8 | * Created by xuzhb on 2021/8/9
9 | * Desc:
10 | */
11 | public class TestMvvmListFragmentViewModel extends BaseListViewModel {
12 |
13 | //第一种写法
14 | // @Override
15 | // public Observable> loadDataFromServer(int page, int count) {
16 | // return ApiHelper.getWangYiNewsByField(page, count);
17 | // }
18 |
19 | //第二种写法
20 | //如果只是从服务器获取并展示列表数据,那么采用第一种写法重写loadDataFromServer返回相应的接口即可
21 | //但如果有需要处理其他逻辑,那么就需要重写loadData,并且在获取到数据后重写对应Activity的observerListDataChange方法,
22 | //在里面调用showData展示列表数据
23 | @Override
24 | public void loadData(int page, int count, boolean showLoadLayout, boolean showLoadingDialog) {
25 | launch(ApiHelper.getWangYiNewsByField(page, count), successData, errorData, false, page == 1);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvvm/AATest/notListType/TestMvvmActivityViewModel.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm.AATest.notListType;
2 |
3 | import com.android.frame.http.model.BaseResponse;
4 | import com.android.frame.mvc.AATest.entity.WeatherBean;
5 | import com.android.frame.mvvm.AATest.server.ApiHelper;
6 | import com.android.frame.mvvm.BaseViewModelWithData;
7 |
8 | /**
9 | * Created by xuzhb on 2021/8/9
10 | * Desc:BaseViewModelWithData的使用,简化了很多,BaseViewModel的使用参见TestMvvmFragmentViewModel
11 | */
12 | public class TestMvvmActivityViewModel extends BaseViewModelWithData> {
13 |
14 | public void showWeatherInfo(String city) {
15 | launchMain(ApiHelper.getWeatherByQuery(city));
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvvm/AATest/server/ApiService.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm.AATest.server;
2 |
3 | import com.android.frame.http.model.BaseListResponse;
4 | import com.android.frame.http.model.BaseResponse;
5 | import com.android.frame.mvc.AATest.entity.NewsListBean;
6 | import com.android.frame.mvc.AATest.entity.WeatherBean;
7 |
8 | import io.reactivex.Observable;
9 | import retrofit2.http.Field;
10 | import retrofit2.http.FormUrlEncoded;
11 | import retrofit2.http.GET;
12 | import retrofit2.http.POST;
13 | import retrofit2.http.Query;
14 |
15 | /**
16 | * Created by xuzhb on 2021/8/10
17 | * Desc:
18 | */
19 | public interface ApiService {
20 |
21 | //获取天气信息,@Query,GET请求
22 | @GET("weather_mini")
23 | Observable> getWeatherByQuery(@Query("city") String city);
24 |
25 | //获取网易新闻,@Field,POST请求
26 | @FormUrlEncoded
27 | @POST("getWangYiNews")
28 | Observable> getWangYiNewsByField(@Field("page") int page, @Field("count") int count);
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvvm/AATest/server/Config.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm.AATest.server;
2 |
3 | /**
4 | * Created by xuzhb on 2021/8/10
5 | * Desc:
6 | */
7 | public class Config {
8 |
9 | public static final String WEATHER_URL = "http://wthrcdn.etouch.cn/";
10 |
11 | public static final String NEWS_URL = "https://api.apiopen.top/";
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvvm/IBaseListView.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by xuzhb on 2021/8/9
7 | */
8 | public interface IBaseListView extends IBaseView {
9 |
10 | /**
11 | * 获取加载的起始页码
12 | */
13 | int getFirstPage();
14 |
15 | /**
16 | * 是否是首次加载
17 | */
18 | boolean isFirstLoad();
19 |
20 | /**
21 | * 获取一页加载的个数
22 | */
23 | int getLoadSize();
24 |
25 | /**
26 | * 显示数据
27 | */
28 | void showData(int page, List list);
29 |
30 | /**
31 | * 处理数据
32 | */
33 | List convertData(List response);
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/frame/mvvm/extra/LiveDataEntity/DialogConfig.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm.extra.LiveDataEntity;
2 |
3 | /**
4 | * Created by xuzhb on 2021/8/9
5 | * Desc:对话框配置信息
6 | */
7 | public class DialogConfig {
8 |
9 | private String message;
10 | private boolean cancelable;
11 |
12 | public DialogConfig(String message, boolean cancelable) {
13 | this.message = message;
14 | this.cancelable = cancelable;
15 | }
16 |
17 | public String getMessage() {
18 | return message;
19 | }
20 |
21 | public void setMessage(String message) {
22 | this.message = message;
23 | }
24 |
25 | public boolean isCancelable() {
26 | return cancelable;
27 | }
28 |
29 | public void setCancelable(boolean cancelable) {
30 | this.cancelable = cancelable;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/util/HandlerUtil.java:
--------------------------------------------------------------------------------
1 | package com.android.util;
2 |
3 | import android.os.Handler;
4 | import android.os.Message;
5 |
6 | import java.lang.ref.WeakReference;
7 |
8 | /**
9 | * Created by xuzhb on 2021/1/13
10 | * Desc:Handler工具类
11 | */
12 | public final class HandlerUtil {
13 |
14 | private HandlerUtil() {
15 | }
16 |
17 | public static class HandlerHolder extends Handler {
18 | WeakReference mListenerWeakReference;
19 |
20 | /**
21 | * 使用必读:推荐在Activity或者Activity内部持有类中实现该接口,不要使用匿名类,可能会被GC
22 | *
23 | * @param listener 收到消息回调接口
24 | */
25 | public HandlerHolder(Callback listener) {
26 | mListenerWeakReference = new WeakReference<>(listener);
27 | }
28 |
29 | @Override
30 | public void handleMessage(Message msg) {
31 | if (mListenerWeakReference != null && mListenerWeakReference.get() != null) {
32 | mListenerWeakReference.get().handleMessage(msg);
33 | }
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/java/src/main/java/com/android/util/NetReceiver.java:
--------------------------------------------------------------------------------
1 | package com.android.util;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.net.ConnectivityManager;
7 |
8 | /**
9 | * Created by xuzhb on 2020/1/5
10 | * Desc:监听网络变化
11 | */
12 | public class NetReceiver extends BroadcastReceiver {
13 |
14 | @Override
15 | public void onReceive(Context context, Intent intent) {
16 | if (intent != null) {
17 | if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
18 | mListener.onNetChange(NetworkUtil.isConnected(context));
19 | }
20 | }
21 | }
22 |
23 | public interface OnNetChangeListener {
24 | void onNetChange(boolean isConnected);
25 | }
26 |
27 | private OnNetChangeListener mListener;
28 |
29 | public void setOnNetChangeListener(OnNetChangeListener listener) {
30 | this.mListener = listener;
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/util/SystemUtil.java:
--------------------------------------------------------------------------------
1 | package com.android.util;
2 |
3 | import android.content.Context;
4 | import android.content.pm.ApplicationInfo;
5 | import android.content.pm.PackageManager;
6 |
7 | /**
8 | * Created by xuzhb on 2019/12/7
9 | * Desc:系统工具
10 | */
11 | public class SystemUtil {
12 |
13 | private static final String TAG = "SystemUtil";
14 |
15 | //获取应用UID
16 | public static int getUid(Context context, String packageName) {
17 | int uid = -1;
18 | try {
19 | PackageManager pm = context.getPackageManager();
20 | ApplicationInfo ai = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
21 | uid = ai.uid;
22 | LogUtil.i(TAG, "label:" + ai.loadLabel(pm) + "\tuid:" + ai.uid);
23 | } catch (PackageManager.NameNotFoundException e) {
24 | e.printStackTrace();
25 | }
26 | return uid;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/util/app/AATest/AppAdapter.java:
--------------------------------------------------------------------------------
1 | package com.android.util.app.AATest;
2 |
3 | import android.content.Context;
4 | import com.android.java.R;
5 | import com.android.util.app.AppInfo;
6 | import com.android.widget.RecyclerView.BaseAdapter;
7 | import com.android.widget.RecyclerView.ViewHolder;
8 |
9 | import java.util.List;
10 |
11 | /**
12 | * Created by xuzhb on 2020/2/5
13 | * Desc:
14 | */
15 | public class AppAdapter extends BaseAdapter {
16 |
17 | public AppAdapter(Context context, List dataList) {
18 | super(context, dataList, R.layout.item_image_with_text);
19 | }
20 |
21 | @Override
22 | protected void bindData(ViewHolder holder, AppInfo data, int position) {
23 | holder.setImageDrawable(R.id.item_iv, data.getIcon())
24 | .setText(R.id.item_tv, data.getLabel());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/util/threadPool/StepThread.java:
--------------------------------------------------------------------------------
1 | package com.android.util.threadPool;
2 |
3 | import java.util.concurrent.Callable;
4 |
5 | /**
6 | * Created by xuzhb on 2020/4/5
7 | * Desc:封装Callable接口
8 | */
9 | public abstract class StepThread implements Callable {
10 |
11 | //初始化
12 | public abstract void init() throws Exception;
13 |
14 | //执行任务并返回最终结果
15 | public abstract V execute() throws Exception;
16 |
17 | //发生异常时回调
18 | public abstract void onError(Exception e);
19 |
20 | //可以做一些最终的资源释放
21 | public abstract void onDestory();
22 |
23 | @Override
24 | public V call() throws Exception {
25 | try {
26 | init();
27 | return execute();
28 | } catch (Exception e) {
29 | onError(e);
30 | } finally {
31 | onDestory();
32 | }
33 | return null;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/FloatWindow/NeedPermission/AATest/TestFloatPageTwoActivity.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission.AATest;
2 |
3 | import android.os.Bundle;
4 |
5 | import com.android.frame.mvc.BaseActivity;
6 | import com.android.java.databinding.ActivityCommonLayoutBinding;
7 | import com.android.util.CommonLayoutUtil;
8 |
9 | /**
10 | * Created by xuzhb on 2021/3/10
11 | * Desc:
12 | */
13 | public class TestFloatPageTwoActivity extends BaseActivity {
14 |
15 | @Override
16 | public void handleView(Bundle savedInstanceState) {
17 | CommonLayoutUtil.initCommonLayout(this, "悬浮窗页面二", false, true, "跳转到悬浮窗页面三");
18 | binding.tv.setText("悬浮窗A不在页面二显示");
19 | }
20 |
21 | @Override
22 | public void initListener() {
23 | binding.btn1.setOnClickListener(v -> {
24 | startActivity(TestFloatPageThreeActivity.class);
25 | });
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/FloatWindow/NeedPermission/IFloatWindow.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * Created by xuzhb on 2021/3/8
7 | * Desc:
8 | */
9 | public interface IFloatWindow {
10 |
11 | void show();
12 |
13 | void hide();
14 |
15 | boolean isShowing();
16 |
17 | int getX();
18 |
19 | int getY();
20 |
21 | void updateX(int x);
22 |
23 | /**
24 | * 更新x坐标
25 | *
26 | * @param screenType 以屏幕宽度或屏幕高度为基准
27 | * @param ratio 占比
28 | */
29 | void updateX(@ScreenType.screenType int screenType, float ratio);
30 |
31 | void updateY(int y);
32 |
33 | /**
34 | * 更新y坐标
35 | *
36 | * @param screenType 以屏幕宽度或屏幕高度为基准
37 | * @param ratio 占比
38 | */
39 | void updateY(@ScreenType.screenType int screenType, float ratio);
40 |
41 | void updateXY(int x, int y);
42 |
43 | View getView();
44 |
45 | //使用FloatWindow.destroy()来取消弹窗,不要手动调用下面的方法
46 | @Deprecated
47 | void dismiss();
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/FloatWindow/NeedPermission/MoveType.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission;
2 |
3 | import androidx.annotation.IntDef;
4 |
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 |
8 | /**
9 | * Created by xuzhb on 2021/3/8
10 | * Desc:移动方式
11 | */
12 | public class MoveType {
13 |
14 | public static final int inactive = 1; //不可移动
15 | public static final int active = 2; //可移动
16 | public static final int slide = 3; //移动松手后贴边
17 | public static final int back = 4; //移动松手后回到原来的位置
18 |
19 | @IntDef({inactive, active, slide, back})
20 | @Retention(RetentionPolicy.SOURCE)
21 | @interface moveType {
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/FloatWindow/NeedPermission/OnPermissionListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission;
2 |
3 | /**
4 | * Created by xuzhb on 2021/3/8
5 | * Desc:权限申请结果回调
6 | */
7 | public interface OnPermissionListener {
8 |
9 | //授权成功
10 | void onSuccess();
11 |
12 | //授权失败
13 | void onFailure();
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/FloatWindow/NeedPermission/OnViewListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission;
2 |
3 | import android.view.View;
4 |
5 | import com.android.widget.ViewHolder;
6 |
7 | /**
8 | * Created by xuzhb on 2021/3/11
9 | * Desc:设置contentView上控件的事件监听
10 | */
11 | public interface OnViewListener {
12 | void onView(ViewHolder holder, View view);
13 | }
14 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/FloatWindow/NeedPermission/OnViewStateListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission;
2 |
3 | /**
4 | * Created by xuzhb on 2021/3/8
5 | * Desc:状态改变监听
6 | */
7 | public interface OnViewStateListener {
8 |
9 | void onPositionUpdate(int x, int y);
10 |
11 | void onShow();
12 |
13 | void onHide();
14 |
15 | void onDismiss();
16 |
17 | void onMoveAnimStart();
18 |
19 | void onMoveAnimEnd();
20 |
21 | void onBackToDesktop();
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/FloatWindow/NeedPermission/ScreenType.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission;
2 |
3 | import androidx.annotation.IntDef;
4 |
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 |
8 | /**
9 | * Created by xuzhb on 2021/3/8
10 | * Desc:选择以屏幕宽度或屏幕高度为基准
11 | */
12 | public class ScreenType {
13 | public static final int width = 0;
14 | public static final int height = 1;
15 |
16 | @IntDef({width, height})
17 | @Retention(RetentionPolicy.SOURCE)
18 | @interface screenType {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/FloatWindow/NoPermission/MoveType.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NoPermission;
2 |
3 | import androidx.annotation.IntDef;
4 |
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 |
8 | /**
9 | * Created by xuzhb on 2021/3/8
10 | * Desc:移动方式
11 | */
12 | public class MoveType {
13 |
14 | public static final int inactive = 1; //不可移动
15 | public static final int active = 2; //可移动
16 | public static final int slide = 3; //移动松手后贴边
17 | public static final int back = 4; //移动松手后回到原来的位置
18 |
19 | @IntDef({inactive, active, slide, back})
20 | @Retention(RetentionPolicy.SOURCE)
21 | @interface moveType {
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/FloatWindow/NoPermission/OnViewListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NoPermission;
2 |
3 | import android.view.View;
4 |
5 | import com.android.widget.ViewHolder;
6 |
7 | /**
8 | * Created by xuzhb on 2021/3/18
9 | * Desc:设置contentView上控件的事件监听
10 | */
11 | public interface OnViewListener {
12 | void onView(ViewHolder holder, View view);
13 | }
14 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/FloatWindow/NoPermission/ScreenType.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NoPermission;
2 |
3 | import androidx.annotation.IntDef;
4 |
5 | import java.lang.annotation.Retention;
6 | import java.lang.annotation.RetentionPolicy;
7 |
8 | /**
9 | * Created by xuzhb on 2021/3/8
10 | * Desc:选择以屏幕宽度或屏幕高度为基准
11 | */
12 | public class ScreenType {
13 | public static final int width = 0;
14 | public static final int height = 1;
15 |
16 | @IntDef({width, height})
17 | @Retention(RetentionPolicy.SOURCE)
18 | @interface screenType {
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/FloatWindow/TestFloatActivity.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow;
2 |
3 | import android.os.Bundle;
4 |
5 | import com.android.frame.mvc.BaseActivity;
6 | import com.android.java.databinding.ActivityCommonLayoutBinding;
7 | import com.android.util.CommonLayoutUtil;
8 | import com.android.widget.FloatWindow.NeedPermission.AATest.TestFloatPageOneActivity;
9 | import com.android.widget.FloatWindow.NoPermission.AATest.TestFloatPageActivity;
10 |
11 | /**
12 | * Created by xuzhb on 2021/3/22
13 | * Desc:
14 | */
15 | public class TestFloatActivity extends BaseActivity {
16 | @Override
17 | public void handleView(Bundle savedInstanceState) {
18 | CommonLayoutUtil.initCommonLayout(this, "悬浮窗", "申请权限", "无需权限");
19 | }
20 |
21 | @Override
22 | public void initListener() {
23 | binding.btn1.setOnClickListener(v -> {
24 | startActivity(TestFloatPageOneActivity.class);
25 | });
26 | binding.btn2.setOnClickListener(v -> {
27 | TestFloatPageActivity.start(this, 1);
28 | });
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PhotoViewer/listener/OnGestureListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener;
2 |
3 | /**
4 | * Created by xuzhb on 2021/1/6
5 | * Desc:手势监听
6 | */
7 | public interface OnGestureListener {
8 |
9 | /**
10 | * 拖动
11 | *
12 | * @param dx 水平方向上拖动的距离
13 | * @param dy 竖直方向上拖动的距离
14 | */
15 | void onDrag(float dx, float dy);
16 |
17 | /**
18 | * 快速滑动
19 | *
20 | * @param startX 滑动起点的x坐标
21 | * @param startY 滑动起点的y坐标
22 | * @param velocityX 水平方向上滑动的速度
23 | * @param velocityY 竖直方向上滑动的速度
24 | */
25 | void onFling(float startX, float startY, float velocityX, float velocityY);
26 |
27 | /**
28 | * 缩放
29 | *
30 | * @param scaleFactor 缩放因子
31 | * @param focusX 组成该手势的两个触点的中点的x坐标,单位是像素
32 | * @param focusY 组成该手势的两个触点的中点的y坐标,单位是像素
33 | */
34 | void onScale(float scaleFactor, float focusX, float focusY);
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PhotoViewer/listener/OnMatrixChangedListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener;
2 |
3 | import android.graphics.RectF;
4 |
5 | /**
6 | * Created by xuzhb on 2021/1/6
7 | * Desc:View的Matrix矩阵变化监听
8 | */
9 | public interface OnMatrixChangedListener {
10 |
11 | /**
12 | * 当View的边界发生变化时回调
13 | *
14 | * @param rect View的新边界
15 | */
16 | void onMatrixChanged(RectF rect);
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PhotoViewer/listener/OnOutsidePhotoTapListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener;
2 |
3 | import android.widget.ImageView;
4 |
5 | /**
6 | * Created by xuzhb on 2021/1/6
7 | * Desc:图片外部区域点击事件监听
8 | */
9 | public interface OnOutsidePhotoTapListener {
10 |
11 | /**
12 | * 点击图片外部区域时回调
13 | */
14 | void onOutsidePhotoTap(ImageView imageView);
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PhotoViewer/listener/OnPhotoTapListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener;
2 |
3 | import android.widget.ImageView;
4 |
5 | /**
6 | * Created by xuzhb on 2021/1/6
7 | * Desc:图片单击事件监听
8 | */
9 | public interface OnPhotoTapListener {
10 |
11 | /**
12 | * 点击图片区域以内时回调,图片区域以外不会回调
13 | *
14 | * @param imageView 点击的图片
15 | * @param x 点击的位置x坐标
16 | * @param y 点击的位置y坐标
17 | * @param xOffset 点击的位置相对于左上角的横向偏移量,百分比形式
18 | * @param yOffset 点击的位置相对于左上角的纵向偏移量,百分比形式
19 | */
20 | void onPhotoTap(ImageView imageView, float x, float y, float xOffset, float yOffset);
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PhotoViewer/listener/OnScaleChangedListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener;
2 |
3 | /**
4 | * Created by xuzhb on 2021/1/6
5 | * Desc:图片缩放监听
6 | */
7 | public interface OnScaleChangedListener {
8 |
9 | /**
10 | * 图片缩放时回调
11 | *
12 | * @param scaleFactor 缩放因子(小于1时缩小,大于1时放大)
13 | * @param focusX 缩放焦点的x坐标
14 | * @param focusY 缩放焦点的y坐标
15 | */
16 | void onScaleChange(float scaleFactor, float focusX, float focusY);
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PhotoViewer/listener/OnSingleFlingListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener;
2 |
3 | import android.view.MotionEvent;
4 |
5 | /**
6 | * Created by xuzhb on 2021/1/6
7 | * Desc:快速滑动监听
8 | */
9 | public interface OnSingleFlingListener {
10 |
11 | /**
12 | * 快速滑动时回调
13 | *
14 | * @param event1 首次接触时的MotionEvent
15 | * @param event2 最后一次接触时的MotionEvent
16 | * @param velocityX 水平滑动的速度
17 | * @param velocityY 竖直滑动的速度
18 | */
19 | boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY);
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PhotoViewer/listener/OnViewDragListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener;
2 |
3 | /**
4 | * Created by xuzhb on 2021/1/8
5 | * Desc:图片拖动监听
6 | */
7 | public interface OnViewDragListener {
8 |
9 | /**
10 | * 拖动图片时回调,当缩放图片时不会触发次回调
11 | *
12 | * @param dx 水平方向上拖动的距离
13 | * @param dy 竖直方向上拖动的距离
14 | */
15 | void onDrag(float dx, float dy);
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PhotoViewer/listener/OnViewTapListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * Created by xuzhb on 2021/1/8
7 | * Desc:ImageView点击事件监听
8 | */
9 | public interface OnViewTapListener {
10 |
11 | /**
12 | * ImageView点击时回调
13 | *
14 | * @param view 点击的ImageView
15 | * @param x 点击的X坐标
16 | * @param y 点击的Y坐标
17 | */
18 | void onViewTap(View view, float x, float y);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PhotoViewer/widget/PhotoViewPager.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.MotionEvent;
6 |
7 | import androidx.annotation.NonNull;
8 | import androidx.annotation.Nullable;
9 | import androidx.viewpager.widget.ViewPager;
10 |
11 | /**
12 | * Created by xuzhb on 2021/1/12
13 | */
14 | public class PhotoViewPager extends ViewPager {
15 |
16 | public PhotoViewPager(@NonNull Context context) {
17 | super(context);
18 | }
19 |
20 | public PhotoViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {
21 | super(context, attrs);
22 | }
23 |
24 | @Override
25 | public boolean onInterceptTouchEvent(MotionEvent ev) {
26 | try {
27 | return super.onInterceptTouchEvent(ev);
28 | } catch (Exception e) {
29 | return false;
30 | }
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PicGetterDialog/AATest/CustomPicGetterDialog.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PicGetterDialog.AATest;
2 |
3 | import android.app.Dialog;
4 | import com.android.java.R;
5 | import com.android.widget.PicGetterDialog.BasePicGetterDialog;
6 | import com.android.widget.ViewHolder;
7 |
8 | /**
9 | * Created by xuzhb on 2020/1/27
10 | * Desc:
11 | */
12 | public class CustomPicGetterDialog extends BasePicGetterDialog {
13 |
14 | public static CustomPicGetterDialog newInstance() {
15 | return new CustomPicGetterDialog();
16 | }
17 |
18 | @Override
19 | public int getLayoutId() {
20 | return R.layout.dialog_custom_pic_getter;
21 | }
22 |
23 | @Override
24 | public void convertView(ViewHolder holder, Dialog dialog) {
25 | holder.setOnClickListener(R.id.camera_btn, v -> {
26 | openCamera(); //拍照
27 | });
28 | holder.setOnClickListener(R.id.gallery_btn, v -> {
29 | openGallery(); //从相册选取照片
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PicGetterDialog/OnPicGetterListener.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PicGetterDialog;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | /**
6 | * Create by xuzhb on 2020/1/23
7 | * Desc:
8 | */
9 | public interface OnPicGetterListener {
10 |
11 | /**
12 | * 图片获取成功
13 | *
14 | * @param bitmap 图片
15 | * @param picPath 图片路径
16 | */
17 | void onSuccess(Bitmap bitmap, String picPath);
18 |
19 | /**
20 | * 图片获取失败
21 | *
22 | * @param errorMsg 错误信息
23 | */
24 | void onFailure(String errorMsg);
25 |
26 | /**
27 | * 取消图片获取
28 | */
29 | void onCancel();
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PicGetterDialog/PicGetterDialog.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PicGetterDialog;
2 |
3 | import android.app.Dialog;
4 | import com.android.java.R;
5 | import com.android.widget.ViewHolder;
6 |
7 | /**
8 | * Create by xuzhb on 2020/1/22
9 | * Desc:拍照或从相册选取选择框
10 | */
11 | public class PicGetterDialog extends BasePicGetterDialog {
12 |
13 | public static PicGetterDialog newInstance() {
14 | return new PicGetterDialog();
15 | }
16 |
17 | @Override
18 | public int getLayoutId() {
19 | return R.layout.dialog_pic_getter;
20 | }
21 |
22 | @Override
23 | public void convertView(ViewHolder holder, Dialog dialog) {
24 | holder.setOnClickListener(R.id.camera_tv, v -> {
25 | openCamera(); //拍照
26 | });
27 | holder.setOnClickListener(R.id.gallery_tv, v -> {
28 | openGallery(); //从相册选取照片
29 | });
30 | holder.setOnClickListener(R.id.cancel_tv, v -> {
31 | onCancel(getDialog()); //取消弹窗
32 | dismiss();
33 | });
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PicGetterDialog/说明.md:
--------------------------------------------------------------------------------
1 | 集成:
2 | 1、build.gradle导入图片裁剪框架'com.yalantis:ucrop:2.2.0'
3 | 2、AndroidManifest配置相应的fileprovider和UCropActivity
4 | 3、混淆
5 | -dontwarn com.yalantis.ucrop**
6 | -keep class com.yalantis.ucrop** { *; }
7 | -keep interface com.yalantis.ucrop** { *; }
8 |
9 | 相关类:
10 | 1、dialog_pic_getter:弹窗布局
11 | 2、pic_getter_file_paths:fileprovider配置,Android 7.0以上的系统需要使用FileProvider兼容拍照
12 | 3、PicProvider:fileprovider
13 | 4、BasePicGetterDialog
14 | 5、PicGetterDialog
15 | 6、OnPicGetterListener
16 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PopupWindow/AATest/PopupWindowAdapter.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PopupWindow.AATest;
2 |
3 | import android.content.Context;
4 | import com.android.java.R;
5 | import com.android.widget.RecyclerView.BaseAdapter;
6 | import com.android.widget.RecyclerView.ViewHolder;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * Create by xuzhb on 2020/1/21
12 | * Desc:
13 | */
14 | public class PopupWindowAdapter extends BaseAdapter {
15 |
16 | public PopupWindowAdapter(Context context, List dataList) {
17 | super(context, dataList, R.layout.item_popup_window);
18 | }
19 |
20 | @Override
21 | protected void bindData(ViewHolder holder, String data, int position) {
22 | holder.setText(R.id.item_tv, data);
23 | if (position == getItemCount() - 1) {
24 | holder.setViewGone(R.id.divider_line);
25 | } else {
26 | holder.setViewVisible(R.id.divider_line);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/PopupWindow/WindowHelper.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.PopupWindow;
2 |
3 | import android.app.Activity;
4 | import android.view.Window;
5 | import android.view.WindowManager;
6 |
7 | import androidx.annotation.FloatRange;
8 |
9 | /**
10 | * Create by xuzhb on 2020/1/21
11 | * Desc:Window辅助类,实现背景灰色效果
12 | */
13 | public class WindowHelper {
14 |
15 | private Activity mActivity;
16 |
17 | public WindowHelper(Activity activity) {
18 | this.mActivity = activity;
19 | }
20 |
21 | //设置外部区域背景透明度,0:完全不透明,1:完全透明
22 | public void setBackGroundAlpha(@FloatRange(from = 0.0, to = 1.0) float alpha) {
23 | Window window = mActivity.getWindow();
24 | WindowManager.LayoutParams lp = window.getAttributes();
25 | lp.alpha = alpha;
26 | window.setAttributes(lp);
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/ProgressBar/TestProgressBarActivity.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.ProgressBar;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 |
6 | import com.android.frame.mvc.BaseActivity;
7 | import com.android.java.databinding.ActivityTestProgressBarBinding;
8 |
9 | /**
10 | * Created by xuzhb on 2020/7/11
11 | * Desc:
12 | */
13 | public class TestProgressBarActivity extends BaseActivity {
14 | @Override
15 | public void handleView(Bundle savedInstanceState) {
16 | int[] rindColorArray = new int[]{Color.parseColor("#0888FF"), Color.parseColor("#6CD0FF")};
17 | binding.arcAv1.startRotate();
18 | binding.arcAv2.setRindColorArray(rindColorArray);
19 | binding.arcAv2.startRotate();
20 | }
21 |
22 | @Override
23 | public void initListener() {
24 |
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/RecyclerView/AATest/entity/DateBean.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.RecyclerView.AATest.entity;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Create by xuzhb on 2020/1/21
7 | * Desc:
8 | */
9 | public class DateBean implements Serializable {
10 |
11 | private String date;
12 |
13 | public DateBean(String date) {
14 | this.date = date;
15 | }
16 |
17 | public String getDate() {
18 | return date;
19 | }
20 |
21 | public void setDate(String date) {
22 | this.date = date;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/RecyclerView/AATest/entity/DetailBean.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.RecyclerView.AATest.entity;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Create by xuzhb on 2020/1/21
7 | * Desc:
8 | */
9 | public class DetailBean implements Serializable {
10 |
11 | private String detail;
12 | private String time;
13 |
14 | public DetailBean(String detail, String time) {
15 | this.detail = detail;
16 | this.time = time;
17 | }
18 |
19 | public String getDetail() {
20 | return detail;
21 | }
22 |
23 | public void setDetail(String detail) {
24 | this.detail = detail;
25 | }
26 |
27 | public String getTime() {
28 | return time;
29 | }
30 |
31 | public void setTime(String time) {
32 | this.time = time;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/RecyclerView/AATest/entity/MonthBean.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.RecyclerView.AATest.entity;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Create by xuzhb on 2020/1/21
7 | * Desc:
8 | */
9 | public class MonthBean implements Serializable {
10 |
11 | private String month;
12 | private String count;
13 |
14 | public MonthBean(String month, String count) {
15 | this.month = month;
16 | this.count = count;
17 | }
18 |
19 | public String getMonth() {
20 | return month;
21 | }
22 |
23 | public void setMonth(String month) {
24 | this.month = month;
25 | }
26 |
27 | public String getCount() {
28 | return count;
29 | }
30 |
31 | public void setCount(String count) {
32 | this.count = count;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/RecyclerView/MultiViewType.java:
--------------------------------------------------------------------------------
1 | package com.android.widget.RecyclerView;
2 |
3 | /**
4 | * Create by xuzhb on 2020/1/20
5 | * Desc:RecyclerView实现多种Item布局
6 | */
7 | public interface MultiViewType {
8 |
9 | /**
10 | * 实现多种item布局
11 | *
12 | * @param data Item对应的数据
13 | * @param position Item的位置
14 | * @param totalCount Item的总数
15 | * @return Item对应的布局类型,使用布局的id进行区分
16 | */
17 | int getLayoutId(T data, int position, int totalCount);
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/java/src/main/java/com/android/widget/ScrollTextView.java:
--------------------------------------------------------------------------------
1 | package com.android.widget;
2 |
3 | import android.content.Context;
4 | import android.text.TextUtils;
5 | import android.util.AttributeSet;
6 |
7 | import androidx.appcompat.widget.AppCompatTextView;
8 |
9 | /**
10 | * Created by xuzhb on 2020/1/6
11 | * Desc:TextView文字滚动显示,即跑马灯效果(不需要获取焦点)
12 | */
13 | public class ScrollTextView extends AppCompatTextView {
14 |
15 | public ScrollTextView(Context context) {
16 | this(context, null);
17 | }
18 |
19 | public ScrollTextView(Context context, AttributeSet attrs) {
20 | this(context, attrs, 0);
21 | }
22 |
23 | public ScrollTextView(Context context, AttributeSet attrs, int defStyleAttr) {
24 | super(context, attrs, defStyleAttr);
25 | initView();
26 | }
27 |
28 | private void initView() {
29 | setSingleLine(true);
30 | setEllipsize(TextUtils.TruncateAt.MARQUEE); //设置跑马灯效果
31 | setMarqueeRepeatLimit(-1); //设置循环滚动为无限循环
32 | }
33 |
34 | @Override
35 | public boolean isFocused() {
36 | return true;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/java/src/main/res/layout/activity_list_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/java/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
17 |
18 |
27 |
28 |
--------------------------------------------------------------------------------
/java/src/main/res/layout/activity_test_bitmap.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
17 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/java/src/main/res/layout/activity_test_capture_gridview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
22 |
23 |
--------------------------------------------------------------------------------
/java/src/main/res/layout/activity_test_capture_listview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/java/src/main/res/layout/activity_test_capture_recyclerview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
17 |
18 |
--------------------------------------------------------------------------------
/java/src/main/res/layout/activity_test_capture_webview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/java/src/main/res/layout/activity_test_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
16 |
17 |
--------------------------------------------------------------------------------
/java/src/main/res/layout/activity_webview.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/java/src/main/res/layout/fragment_test_mvc.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/java/src/main/res/layout/fragment_test_mvc_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/java/src/main/res/layout/fragment_webview.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/java/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Java
3 |
4 |
--------------------------------------------------------------------------------
/java/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/java/src/test/java/com/android/java/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.android.java;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/kotlin/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/kotlin/src/androidTest/java/com/android/basicproject/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.android.basicproject
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getTargetContext()
22 | assertEquals("com.android.basicproject", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/base/DontSwipeBack.kt:
--------------------------------------------------------------------------------
1 | package com.android.base
2 |
3 | /**
4 | * Created by xuzhb on 2020/11/4
5 | * Desc:不需要侧滑退出Activity
6 | */
7 | interface DontSwipeBack
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/TestLeakActivity.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame
2 |
3 | import android.content.Context
4 | import android.os.Bundle
5 | import com.android.basicproject.databinding.ActivityCommonLayoutBinding
6 | import com.android.frame.mvc.BaseActivity
7 | import com.android.util.initCommonLayout
8 |
9 | /**
10 | * Created by xuzhb on 2019/8/31
11 | * Desc:测试内存泄漏
12 | */
13 | class TestLeakActivity : BaseActivity() {
14 |
15 | companion object {
16 | var mContext: Context? = null
17 | }
18 |
19 | override fun handleView(savedInstanceState: Bundle?) {
20 | mContext = this //测试内存泄漏
21 | initCommonLayout(this, "测试内存泄漏")
22 | }
23 |
24 | override fun initListener() {
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/camera/zxing/util/QRConstant.java:
--------------------------------------------------------------------------------
1 | package com.android.frame.camera.zxing.util;
2 |
3 | /**
4 | * Created by xuzhb on 2019/11/16
5 | * Desc:
6 | */
7 | public class QRConstant {
8 |
9 | public static final String SCAN_QRCODE_RESULT = "SCAN_QRCODE_RESULT"; //扫描结果
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/guide/SimpleViewAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.guide
2 |
3 | import android.view.View
4 | import android.view.ViewGroup
5 | import androidx.viewpager.widget.PagerAdapter
6 |
7 | /**
8 | * Created by xuzhb on 2020/12/28
9 | * Desc:
10 | */
11 | class SimpleViewAdapter(private val viewList: MutableList) : PagerAdapter() {
12 |
13 | //view是否由对象产生,官方写view == `object`即可
14 | override fun isViewFromObject(view: View, `object`: Any): Boolean = view == `object`
15 |
16 | //数据源的数目
17 | override fun getCount(): Int = viewList.size
18 |
19 | //销毁一个页卡(即ViewPager的一个item)
20 | override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
21 | container.removeView(viewList[position])
22 | }
23 |
24 | //对应页卡添加上数据
25 | override fun instantiateItem(container: ViewGroup, position: Int): Any {
26 | container.addView(viewList[position]) //千万别忘记添加到container
27 | return viewList[position]
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/http/AATest/UrlConstant.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.http.AATest
2 |
3 | /**
4 | * Created by xuzhb on 2019/8/9
5 | * Desc:
6 | */
7 | object UrlConstant {
8 |
9 | const val BAIDU_URL = "https://www.baidu.com/"
10 |
11 | const val WEATHER_URL = "http://wthrcdn.etouch.cn/"
12 |
13 | const val NEWS_URL = "https://api.apiopen.top/"
14 |
15 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/http/AATest/bean/NewsListBean.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.http.AATest.bean
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Created by xuzhb on 2019/10/27
7 | * Desc:
8 | */
9 | data class NewsListBean(
10 | val code: Int,
11 | val message: String,
12 | val result: MutableList?
13 | ) : Serializable {
14 | data class ResultBean(
15 | val path: String,
16 | val image: String,
17 | val title: String,
18 | val passtime: String
19 | ) : Serializable
20 |
21 | fun isSuccess(): Boolean = code == 200
22 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/http/CookieJarManage.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.http
2 |
3 | import okhttp3.Cookie
4 | import okhttp3.CookieJar
5 | import okhttp3.HttpUrl
6 |
7 | /**
8 | * Created by xuzhb on 2019/8/8
9 | * Desc:持久化Cookie管理
10 | */
11 | class CookieJarManage : CookieJar {
12 |
13 | companion object {
14 | //单例对象
15 | val instance = SingleTonHolder.holder
16 | }
17 |
18 | //静态内部类单例模式
19 | private object SingleTonHolder {
20 | val holder = CookieJarManage()
21 | }
22 |
23 | private val cookieStore = HashMap>()
24 |
25 | //网路访问后将服务器返回的cookies和对应的url存储在cookieStore中
26 | override fun saveFromResponse(url: HttpUrl, cookies: MutableList) {
27 | cookieStore.put(url.host(), cookies)
28 | }
29 |
30 | //网路访问开始的时候,根据访问的url去查找cookie,然后将cokies放到请求头里面
31 | override fun loadForRequest(url: HttpUrl): MutableList =
32 | cookieStore.get(url.host()) ?: mutableListOf() //cookieStore.get(url)为null时返回mutableListOf()
33 |
34 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/http/SchedulerUtil.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.http
2 |
3 | import io.reactivex.ObservableTransformer
4 | import io.reactivex.android.schedulers.AndroidSchedulers
5 | import io.reactivex.schedulers.Schedulers
6 |
7 | /**
8 | * Created by xuzhb on 2019/8/8
9 | * Desc:简化subscribeOn和observeOn调用
10 | */
11 | object SchedulerUtil {
12 |
13 | fun ioToMain(): ObservableTransformer {
14 | return ObservableTransformer { observable ->
15 | observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
16 | }
17 | }
18 |
19 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/http/interceptor/MaxRetryInterceptor.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.http.interceptor
2 |
3 | import com.android.util.LogUtil
4 | import okhttp3.Interceptor
5 | import okhttp3.Response
6 |
7 | /**
8 | * Created by xuzhb on 2020/8/9
9 | * Desc:限制最多重试次数的拦截器
10 | */
11 | class MaxRetryInterceptor(private val maxRetryCount: Int) : Interceptor {
12 |
13 | companion object {
14 | private const val TAG = "MaxRetryInterceptor"
15 | }
16 |
17 | private var retryCount = 1
18 |
19 | override fun intercept(chain: Interceptor.Chain): Response {
20 | val request = chain.request()
21 | LogUtil.w(TAG, "retry count:$retryCount")
22 | var response = chain.proceed(request) //默认请求1次
23 | while (!response.isSuccessful && retryCount < maxRetryCount) {
24 | retryCount++
25 | LogUtil.w(TAG, "retry count:$retryCount")
26 | response = chain.proceed(request) //重试
27 | }
28 | return response
29 | }
30 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/http/model/BaseListResponse.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.http.model
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Created by xuzhb on 2019/8/8
7 | * Desc:bean基类,列表类型
8 | */
9 | class BaseListResponse(
10 | val code: Int,
11 | val msg: String,
12 | val data: MutableList?
13 | ) : Serializable {
14 | fun isSuccess(): Boolean = code == 200
15 | fun isTokenOut(): Boolean = code == -111 //登录失效,假设code是-111
16 | fun getMessage(): String = msg
17 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/http/model/BaseResponse.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.http.model
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Created by xuzhb on 2019/8/8
7 | * Desc:bean基类,非列表类型
8 | */
9 | class BaseResponse(
10 | val code: Int,
11 | val msg: String,
12 | val data: T?
13 | ) : Serializable {
14 | fun isSuccess(): Boolean = code == 200
15 | fun isTokenOut(): Boolean = code == -111 //登录失效,假设code是-111
16 | fun getMessage(): String = msg
17 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvc/AATest/TestFragmentMvc.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc.AATest
2 |
3 | import android.os.Bundle
4 | import com.android.basicproject.R
5 | import com.android.basicproject.databinding.ActivityTestFragmentBinding
6 | import com.android.frame.mvc.BaseActivity
7 |
8 | /**
9 | * Created by xuzhb on 2020/12/30
10 | * Desc:
11 | */
12 | class TestFragmentMvc : BaseActivity() {
13 |
14 | override fun handleView(savedInstanceState: Bundle?) {
15 | when (intent.getIntExtra("fragment_type", 1)) {
16 | 1 -> {
17 | mTitleBar?.titleText = "基类Fragment(MVC)"
18 | supportFragmentManager.beginTransaction().add(R.id.content_fl, TestMvcFragment.newInstance()).commit()
19 | }
20 | 2 -> {
21 | mTitleBar?.titleText = "列表Fragment(MVC)"
22 | supportFragmentManager.beginTransaction().add(R.id.content_fl, TestMvcListFragment.newInstance()).commit()
23 | }
24 | }
25 | }
26 |
27 | override fun initListener() {
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvc/AATest/adapter/NewsListAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc.AATest.adapter
2 |
3 | import com.android.basicproject.R
4 | import com.android.frame.mvc.AATest.entity.NewsListBean
5 | import com.android.frame.mvc.extra.RecyclerView.LoadMoreAdapter
6 | import com.android.util.SizeUtil
7 | import com.android.util.glide.GlideUtil
8 | import com.bumptech.glide.load.resource.bitmap.RoundedCorners
9 | import com.chad.library.adapter.base.viewholder.BaseViewHolder
10 |
11 | /**
12 | * Created by xuzhb on 2020/12/30
13 | * Desc:
14 | */
15 | class NewsListAdapter : LoadMoreAdapter(R.layout.item_test_load_more) {
16 | override fun convert(holder: BaseViewHolder, item: NewsListBean) {
17 | GlideUtil.showImageFromUrl(holder.getView(R.id.image_iv), item.image, RoundedCorners(SizeUtil.dp2pxInt(6f)))
18 | holder.setText(R.id.title_tv, item.title).setText(R.id.time_tv, item.passtime)
19 | }
20 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvc/AATest/entity/NewsListBean.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc.AATest.entity
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Created by xuzhb on 2020/12/30
7 | * Desc:
8 | */
9 | data class NewsListBean(
10 | val path: String,
11 | val image: String,
12 | val title: String,
13 | val passtime: String
14 | ) : Serializable
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvc/AATest/entity/WeatherBean.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc.AATest.entity
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Created by xuzhb on 2020/12/30
7 | * Desc:
8 | */
9 | data class WeatherBean(
10 | val yesterday: YesterdayBean,
11 | val city: String,
12 | val forecast: List,
13 | val ganmao: String,
14 | val wendu: String
15 | ) : Serializable {
16 |
17 | data class YesterdayBean(
18 | val date: String,
19 | val high: String,
20 | val fx: String,
21 | val low: String,
22 | val fl: String,
23 | val type: String
24 | ) : Serializable
25 |
26 | data class ForecastBean(
27 | val date: String,
28 | val high: String,
29 | val fengli: String,
30 | val low: String,
31 | val fengxiang: String,
32 | val type: String
33 | ) : Serializable
34 |
35 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvc/AATest/server/ApiService.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc.AATest.server
2 |
3 | import io.reactivex.Observable
4 | import okhttp3.ResponseBody
5 | import retrofit2.http.*
6 |
7 | /**
8 | * Created by xuzhb on 2020/7/29
9 | * Desc:
10 | */
11 | interface ApiService {
12 |
13 | //获取天气信息,@Query,GET请求
14 | @GET("weather_mini")
15 | fun getWeatherByQuery(@Query("city") city: String): Observable
16 |
17 | //获取网易新闻,@Field,POST请求
18 | @FormUrlEncoded
19 | @POST("getWangYiNews")
20 | fun getWangYiNewsByField(@Field("page") page: Int, @Field("count") count: Int): Observable
21 |
22 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvc/AATest/server/Config.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc.AATest.server
2 |
3 | /**
4 | * Created by xuzhb on 2020/12/30
5 | * Desc:
6 | */
7 | object Config {
8 |
9 | const val WEATHER_URL = "http://wthrcdn.etouch.cn/"
10 |
11 | const val NEWS_URL = "https://api.apiopen.top/"
12 |
13 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvc/IBaseListView.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc
2 |
3 | /**
4 | * Created by xuzhb on 2021/8/13
5 | */
6 | interface IBaseListView : IBaseView {
7 |
8 | /**
9 | * 获取加载的起始页码
10 | */
11 | fun getFirstPage(): Int
12 |
13 | /**
14 | * 是否是首次加载
15 | */
16 | fun isFirstLoad(): Boolean
17 |
18 | /**
19 | * 获取一页加载的个数
20 | */
21 | fun getLoadSize(): Int
22 |
23 | /**
24 | * 显示数据
25 | */
26 | fun showData(page: Int, list: MutableList?)
27 |
28 | /**
29 | * 处理数据
30 | */
31 | fun convertData(response: MutableList?): MutableList?
32 |
33 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvc/extra/RecyclerView/CustomLoadMoreView.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc.extra.RecyclerView
2 |
3 | import android.view.LayoutInflater
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import com.android.basicproject.R
7 | import com.chad.library.adapter.base.loadmore.BaseLoadMoreView
8 | import com.chad.library.adapter.base.viewholder.BaseViewHolder
9 |
10 | /**
11 | * Created by xuzhb on 2020/7/29
12 | * Desc:自定义加载更多的脚布局
13 | */
14 | class CustomLoadMoreView : BaseLoadMoreView() {
15 |
16 | override fun getLoadComplete(holder: BaseViewHolder): View = holder.getView(R.id.complete_fl)
17 |
18 | override fun getLoadEndView(holder: BaseViewHolder): View = holder.getView(R.id.end_fl)
19 |
20 | override fun getLoadFailView(holder: BaseViewHolder): View = holder.getView(R.id.fail_fl)
21 |
22 | override fun getLoadingView(holder: BaseViewHolder): View = holder.getView(R.id.loading_ll)
23 |
24 | override fun getRootView(parent: ViewGroup): View =
25 | LayoutInflater.from(parent.context).inflate(R.layout.view_load_more, parent, false);
26 |
27 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvc/extra/RecyclerView/LoadMoreAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvc.extra.RecyclerView
2 |
3 | import androidx.annotation.LayoutRes
4 | import com.chad.library.adapter.base.BaseQuickAdapter
5 | import com.chad.library.adapter.base.module.LoadMoreModule
6 | import com.chad.library.adapter.base.viewholder.BaseViewHolder
7 |
8 | /**
9 | * Created by xuzhb on 2020/7/28
10 | * Desc:上拉加载更多
11 | */
12 | abstract class LoadMoreAdapter @JvmOverloads constructor(
13 | @LayoutRes private val layoutResId: Int,
14 | data: MutableList? = null
15 | ) : BaseQuickAdapter(layoutResId, data), LoadMoreModule
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvp/AATest/listType/TestMvpListModel.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp.AATest.listType
2 |
3 | import com.android.frame.http.RetrofitFactory
4 | import com.android.frame.http.SchedulerUtil
5 | import com.android.frame.http.model.BaseListResponse
6 | import com.android.frame.mvc.AATest.convert.NewsFunction
7 | import com.android.frame.mvc.AATest.entity.NewsListBean
8 | import com.android.frame.mvc.AATest.server.ApiService
9 | import com.android.frame.mvc.AATest.server.Config
10 | import io.reactivex.Observable
11 | import java.util.concurrent.TimeUnit
12 |
13 | /**
14 | * Created by xuzhb on 2021/1/5
15 | * Desc:
16 | */
17 | class TestMvpListModel {
18 |
19 | fun getWangYiNewsByField(page: Int, count: Int): Observable> {
20 | return RetrofitFactory.instance.createService(ApiService::class.java, Config.NEWS_URL)
21 | .getWangYiNewsByField(page, count)
22 | .delay(1, TimeUnit.SECONDS) //模拟延迟一段时间后请求到数据的情况
23 | .map(NewsFunction())
24 | .compose(SchedulerUtil.ioToMain())
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvp/AATest/listType/TestMvpListView.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp.AATest.listType
2 |
3 | import com.android.frame.mvc.AATest.entity.NewsListBean
4 | import com.android.frame.mvp.IBaseListView
5 |
6 | /**
7 | * Created by xuzhb on 2021/1/5
8 | * Desc:
9 | */
10 | interface TestMvpListView : IBaseListView {
11 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvp/AATest/notListType/TestMvpModel.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp.AATest.notListType
2 |
3 | import com.android.frame.http.RetrofitFactory
4 | import com.android.frame.http.SchedulerUtil
5 | import com.android.frame.http.model.BaseResponse
6 | import com.android.frame.mvc.AATest.convert.WeatherFunction
7 | import com.android.frame.mvc.AATest.entity.WeatherBean
8 | import com.android.frame.mvc.AATest.server.ApiService
9 | import com.android.frame.mvc.AATest.server.Config
10 | import io.reactivex.Observable
11 | import java.util.concurrent.TimeUnit
12 |
13 | /**
14 | * Created by xuzhb on 2021/1/5
15 | * Desc:
16 | */
17 | class TestMvpModel {
18 |
19 | fun getWeatherInfo(city: String): Observable> {
20 | return RetrofitFactory.instance.createService(ApiService::class.java, Config.WEATHER_URL, cache = true)
21 | .getWeatherByQuery(city)
22 | .delay(1, TimeUnit.SECONDS) //模拟延迟一段时间后请求到数据的情况
23 | .map(WeatherFunction())
24 | .compose(SchedulerUtil.ioToMain())
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvp/AATest/notListType/TestMvpView.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp.AATest.notListType
2 |
3 | import com.android.frame.mvc.AATest.entity.WeatherBean
4 | import com.android.frame.mvp.IBaseView
5 |
6 | /**
7 | * Created by xuzhb on 2021/1/5
8 | * Desc:
9 | */
10 | interface TestMvpView : IBaseView {
11 |
12 | fun showWeatherInfo(city: String, bean: WeatherBean?)
13 |
14 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvp/BasePresenter.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp
2 |
3 | /**
4 | * Created by xuzhb on 2019/12/29
5 | * Desc:MVP中的基类Presenter
6 | */
7 | open class BasePresenter {
8 |
9 | protected var mView: V? = null
10 |
11 | //绑定View
12 | fun attachView(view: V) {
13 | this.mView = view
14 | }
15 |
16 | //解绑View
17 | fun detachView() {
18 | this.mView = null
19 | }
20 |
21 | fun isAttach(): Boolean {
22 | return mView != null
23 | }
24 |
25 | //加载数据,进入页面时默认就会进行加载,请务必重写refreshData,当加载失败点击重试或者下拉刷新时会调用这个方法
26 | open fun refreshData() {
27 |
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvp/CommonBaseActivity.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp
2 |
3 | import androidx.viewbinding.ViewBinding
4 |
5 | /**
6 | * Created by xuzhb on 2019/12/29
7 | * Desc:不需要额外声明View和Presenter的Activity的父类
8 | */
9 | abstract class CommonBaseActivity : BaseActivity>(), IBaseView {
10 | override fun getPresenter(): BasePresenter = BasePresenter()
11 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvp/CommonBaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp
2 |
3 | import androidx.viewbinding.ViewBinding
4 |
5 | /**
6 | * Created by xuzhb on 2019/12/29
7 | * Desc:不需要额外声明View和Presenter的Fragment的父类
8 | */
9 | abstract class CommonBaseFragment : BaseFragment>(), IBaseView {
10 | override fun getPresenter(): BasePresenter = BasePresenter()
11 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvp/IBaseListView.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvp
2 |
3 | /**
4 | * Created by xuzhb on 2020/7/22
5 | * Desc:列表数据对应的基类View
6 | */
7 | interface IBaseListView : IBaseView {
8 |
9 | /**
10 | * 获取当前加载的页码
11 | */
12 | fun getCurrentPage(): Int
13 |
14 | /**
15 | * 设置当前加载的页码
16 | */
17 | fun setCurrentPage(page: Int)
18 |
19 | /**
20 | * 获取加载的起始页码
21 | */
22 | fun getFirstPage(): Int
23 |
24 | /**
25 | * 是否是首次加载
26 | */
27 | fun isFirstLoad(): Boolean
28 |
29 | /**
30 | * 获取一页加载的个数
31 | */
32 | fun getLoadSize(): Int
33 |
34 | /**
35 | * 显示数据
36 | */
37 | fun showData(page: Int, list: MutableList?)
38 |
39 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvp/注意点.md:
--------------------------------------------------------------------------------
1 | BaseCompatActivity:基类Activity
2 | BaseFragment:基类Fragment
3 | IBaseView:基类View
4 | BasePresenter:基类Presenter
5 | CommonBaseActivity:不需要额外声明View和Presenter的Activity父类
6 | CommonBaseFragment:不需要额外声明View和Presenter的Fragment父类
7 | LoadingDialog:自定义加载框
8 | CustomObserver:自定义Observer,加入加载框和网络错误的处理
9 | NetReceiver:广播监听网络变化,动态注册
10 | activity_list_layout:通用的列表布局,包括标题栏和layout_net_error和layout_recycler_view
11 | layout_net_error:网络错误提示布局
12 | layout_recycler_view:通用的列表刷新子布局,包括一个SwipeRefreshLayout和一个RecyclerView
13 |
14 | 集成时注意:
15 | 1、实现BaseCompatActivity和BaseFragment的gotoLogin()方法
16 | 2、处理CustomObserver中登录失效的code,目前暂定登录过期的code是-1001
17 | 3、处理基类Bean,即BaseResponse和BaseListResponse的结构
18 | 4、处理基类Bean接口请求成功的code,目前暂定接口请求成功的code是200
19 |
20 |
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvvm/AATest/convert/CustomRequestBodyConverter.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm.AATest.convert
2 |
3 | import com.google.gson.Gson
4 | import com.google.gson.TypeAdapter
5 | import okhttp3.MediaType
6 | import okhttp3.RequestBody
7 | import okio.Buffer
8 | import retrofit2.Converter
9 | import java.io.OutputStreamWriter
10 | import java.nio.charset.Charset
11 |
12 | /**
13 | * Created by xuzhb on 2021/8/6
14 | * Desc:
15 | */
16 | class CustomRequestBodyConverter(val gson: Gson, val adapter: TypeAdapter) : Converter {
17 |
18 | private val MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8")
19 | private val UTF_8 = Charset.forName("UTF-8")
20 |
21 | override fun convert(value: T): RequestBody? {
22 | val buffer = Buffer()
23 | val writer = OutputStreamWriter(buffer.outputStream(), UTF_8)
24 | val jsonWriter = gson.newJsonWriter(writer)
25 | adapter.write(jsonWriter, value)
26 | jsonWriter.close()
27 | return RequestBody.create(MEDIA_TYPE, buffer.readByteString())
28 | }
29 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvvm/AATest/notListType/TestMvvmActivityViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm.AATest.notListType
2 |
3 | import com.android.frame.http.model.BaseResponse
4 | import com.android.frame.mvc.AATest.entity.WeatherBean
5 | import com.android.frame.mvvm.AATest.server.ApiHelper
6 | import com.android.frame.mvvm.BaseViewModelWithData
7 |
8 | /**
9 | * Created by xuzhb on 2021/8/6
10 | * Desc:BaseViewModelWithData的使用,简化了很多,BaseViewModel的使用参见TestMvvmFragmentViewModel
11 | */
12 | class TestMvvmActivityViewModel : BaseViewModelWithData>() {
13 |
14 | fun showWeatherInfo(city: String) {
15 | launchMain({ ApiHelper.getWeatherByQuery(city) })
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvvm/AATest/server/ApiService.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm.AATest.server
2 |
3 | import com.android.frame.http.model.BaseListResponse
4 | import com.android.frame.http.model.BaseResponse
5 | import com.android.frame.mvc.AATest.entity.NewsListBean
6 | import com.android.frame.mvc.AATest.entity.WeatherBean
7 | import retrofit2.http.*
8 |
9 | /**
10 | * Created by xuzhb on 2021/8/6
11 | * Desc:
12 | */
13 | interface ApiService {
14 |
15 | //获取天气信息,@Query,GET请求
16 | @GET("weather_mini")
17 | suspend fun getWeatherByQuery(@Query("city") city: String): BaseResponse
18 |
19 | //获取网易新闻,@Field,POST请求
20 | @FormUrlEncoded
21 | @POST("getWangYiNews")
22 | suspend fun getWangYiNewsByField(@Field("page") page: Int, @Field("count") count: Int): BaseListResponse
23 |
24 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvvm/AATest/server/Config.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm.AATest.server
2 |
3 | /**
4 | * Created by xuzhb on 2020/12/30
5 | * Desc:
6 | */
7 | object Config {
8 |
9 | const val WEATHER_URL = "http://wthrcdn.etouch.cn/"
10 |
11 | const val NEWS_URL = "https://api.apiopen.top/"
12 |
13 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvvm/BaseListViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.android.frame.http.model.BaseListResponse
5 | import com.android.frame.mvvm.extra.LiveDataEntity.ErrorResponse
6 | import kotlinx.coroutines.CoroutineScope
7 |
8 | /**
9 | * Created by xuzhb on 2021/8/7
10 | * Desc:列表数据对应的基类ViewModel
11 | */
12 | open class BaseListViewModel : BaseViewModel() {
13 |
14 | var successData = MutableLiveData>()
15 | var errorData = MutableLiveData>>()
16 |
17 | //分页加载
18 | open fun loadData(
19 | page: Int,
20 | count: Int,
21 | showLoadLayout: Boolean = true, //是否显示加载状态布局
22 | showLoadingDialog: Boolean = false
23 | ) {
24 | loadDataFromServer(page, count)?.let {
25 | launch(it, successData, errorData, showLoadLayout, showLoadingDialog)
26 | }
27 | }
28 |
29 | //从服务器按页加载数据
30 | open fun loadDataFromServer(page: Int, count: Int): (suspend CoroutineScope.() -> BaseListResponse)? = null
31 |
32 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvvm/BaseViewModelWithData.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm
2 |
3 | import androidx.lifecycle.MutableLiveData
4 | import com.android.frame.mvvm.extra.LiveDataEntity.ErrorResponse
5 | import kotlinx.coroutines.CoroutineScope
6 |
7 | /**
8 | * Created by xuzhb on 2021/8/7
9 | * Desc:基类ViewModel的进一步封装,携带数据结构,包含了主接口的请求方法,
10 | * 可以通过successData处理请求成功的情况,通过errorData处理请求失败的情况
11 | */
12 | abstract class BaseViewModelWithData : BaseViewModel() {
13 |
14 | var successData = MutableLiveData()
15 | var errorData = MutableLiveData>()
16 |
17 | //请求主接口
18 | fun launchMain(
19 | block: suspend CoroutineScope.() -> T, //请求接口方法,T表示data实体泛型
20 | showLoadLayout: Boolean = true, //是否显示加载状态布局
21 | showLoadingDialog: Boolean = false, //是否显示加载弹窗
22 | message: String = "加载中", //加载弹窗的提示文本
23 | cancelable: Boolean = true //加载弹窗是否可以点击取消
24 | ) {
25 | launch(block, successData, errorData, showLoadLayout, showLoadingDialog, message, cancelable, true)
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvvm/CommonBaseActivity.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm
2 |
3 | import android.view.LayoutInflater
4 | import androidx.lifecycle.ViewModelProvider
5 | import androidx.viewbinding.ViewBinding
6 | import java.lang.reflect.ParameterizedType
7 |
8 | /**
9 | * Created by xuzhb on 2021/8/6
10 | * Desc:不需要额外声明ViewModel的Activity的父类
11 | */
12 | abstract class CommonBaseActivity : BaseActivity(), IBaseView {
13 |
14 | override fun initViewBindingAndViewModel() {
15 | val superclass = javaClass.genericSuperclass
16 | val vbClass = (superclass as ParameterizedType).actualTypeArguments[0] as Class
17 | val method = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
18 | binding = method.invoke(null, layoutInflater) as VB
19 | viewModel = ViewModelProvider(this).get((BaseViewModel())::class.java)
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvvm/CommonBaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm
2 |
3 | import android.view.LayoutInflater
4 | import androidx.lifecycle.ViewModelProvider
5 | import androidx.viewbinding.ViewBinding
6 | import java.lang.reflect.ParameterizedType
7 |
8 | /**
9 | * Created by xuzhb on 2021/8/7
10 | * Desc:不需要额外声明ViewModel的Fragment的父类
11 | */
12 | abstract class CommonBaseFragment : BaseFragment(), IBaseView {
13 |
14 | override fun initViewBindingAndViewModel() {
15 | val superclass = javaClass.genericSuperclass
16 | val vbClass = (superclass as ParameterizedType).actualTypeArguments[0] as Class
17 | val method = vbClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
18 | binding = method.invoke(null, layoutInflater) as VB
19 | viewModel = ViewModelProvider(this).get((BaseViewModel())::class.java)
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvvm/IBaseListView.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm
2 |
3 | /**
4 | * Created by xuzhb on 2021/8/7
5 | */
6 | interface IBaseListView : IBaseView {
7 |
8 | /**
9 | * 获取加载的起始页码
10 | */
11 | fun getFirstPage(): Int
12 |
13 | /**
14 | * 是否是首次加载
15 | */
16 | fun isFirstLoad(): Boolean
17 |
18 | /**
19 | * 获取一页加载的个数
20 | */
21 | fun getLoadSize(): Int
22 |
23 | /**
24 | * 显示数据
25 | */
26 | fun showData(page: Int, list: MutableList?)
27 |
28 | /**
29 | * 处理数据
30 | */
31 | fun convertData(response: MutableList?): MutableList?
32 |
33 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvvm/IBaseView.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm
2 |
3 | /**
4 | * Created by xuzhb on 2021/8/5
5 | */
6 | interface IBaseView {
7 |
8 | /**
9 | * 显示加载弹窗,表示正在加载数据
10 | * @param message 加载中的文本提示
11 | * @param cancelable 用户是否可取消加载弹窗,默认可以
12 | */
13 | fun showLoadingDialog(message: String = "加载中", cancelable: Boolean = true)
14 |
15 | /**
16 | * 显示加载状态布局,表示正在加载数据,一般和showLoadingDialog只有一个会出现
17 | */
18 | fun showLoadingLayout()
19 |
20 | /**
21 | * 数据加载完成,此时可以做一些通用的处理,如取消加载弹窗、完成下拉刷新动作等
22 | * @param isError 数据是否加载成功,为true时表示数据加载失败
23 | */
24 | fun loadFinish(isError: Boolean)
25 |
26 | /**
27 | * 显示Toast
28 | * @param text 提示的文本内容
29 | * @param isCenter 是否居中显示,true表示居中显示,默认为false
30 | * @param longToast 显示长Toast还是短Toast,默认为Toast.LENGTH_SHORT,即短Toast
31 | */
32 | fun showToast(text: CharSequence, isCenter: Boolean = true, longToast: Boolean = false)
33 |
34 | /**
35 | * 跳转到登录界面
36 | */
37 | fun gotoLogin()
38 |
39 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvvm/extra/LiveDataEntity/DialogConfig.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm.extra.LiveDataEntity
2 |
3 | /**
4 | * Created by xuzhb on 2021/8/5
5 | * Desc:对话框配置信息
6 | */
7 | data class DialogConfig(
8 | val message: String,
9 | val cancelable: Boolean
10 | )
11 |
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/frame/mvvm/extra/LiveDataEntity/ErrorResponse.kt:
--------------------------------------------------------------------------------
1 | package com.android.frame.mvvm.extra.LiveDataEntity
2 |
3 | /**
4 | * Created by xuzhb on 2021/8/5
5 | * Desc:接口请求失败结果
6 | * 接口请求失败分为两种情况:一种是接口自己返回失败结果,此时isException为false,
7 | * 另一种是接口访问异常,如网络无连接导致无法访问,此时isException为true
8 | */
9 | data class ErrorResponse(
10 | val isException: Boolean, //访问接口是否发生异常,true时exception不为空,false时response不为空
11 | val message: String, //错误信息
12 | val exception: Throwable?, //异常信息,此时isException为true
13 | val response: T? //接口返回结果,此时isException为false
14 | )
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/util/ByteUnit.kt:
--------------------------------------------------------------------------------
1 | package com.android.util
2 |
3 | import androidx.annotation.StringDef
4 | import kotlin.math.pow
5 |
6 | /**
7 | * Created by xuzhb on 2020/12/1
8 | * Desc:流量的单位
9 | */
10 | object ByteUnit {
11 |
12 | const val B = "byte"
13 | const val KB = "kb"
14 | const val MB = "mb"
15 | const val GB = "gb"
16 |
17 | @StringDef(B, KB, MB, GB)
18 | @kotlin.annotation.Retention(AnnotationRetention.SOURCE)
19 | annotation class ByteUnitDef
20 |
21 | private const val UNIT = 1024.0
22 |
23 | fun convertByteUnit(totalBytes: Double, @ByteUnitDef unit: String): Double {
24 | var totalBytes = totalBytes
25 | if (totalBytes > 0) {
26 | when (unit) {
27 | KB -> totalBytes /= UNIT.pow(1.0)
28 | MB -> totalBytes /= UNIT.pow(2.0)
29 | GB -> totalBytes /= UNIT.pow(3.0)
30 | }
31 | }
32 | return totalBytes
33 | }
34 |
35 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/util/CapturePicture/TestCaptureWebViewActivity.kt:
--------------------------------------------------------------------------------
1 | package com.android.util.CapturePicture
2 |
3 | import android.os.Bundle
4 | import com.android.basicproject.databinding.ActivityTestCaptureWebviewBinding
5 | import com.android.frame.mvc.BaseActivity
6 | import com.android.util.bitmap.BitmapUtil
7 |
8 | /**
9 | * Created by xuzhb on 2021/5/13
10 | * Desc:
11 | */
12 | class TestCaptureWebViewActivity : BaseActivity() {
13 |
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | CapturePictureUtil.enableSlowWholeDocumentDraw()
16 | super.onCreate(savedInstanceState)
17 | }
18 |
19 | override fun handleView(savedInstanceState: Bundle?) {
20 | binding.webView.loadUrl("https://xw.qq.com/")
21 | }
22 |
23 | override fun initListener() {
24 | mTitleBar?.setOnRightTextClickListener {
25 | val bitmap = CapturePictureUtil.captureByWebView(binding.webView)
26 | BitmapUtil.saveBitmapToGallery(this, bitmap, "WebView截图")
27 | }
28 | }
29 |
30 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/util/NetReceiver.kt:
--------------------------------------------------------------------------------
1 | package com.android.util
2 |
3 | import android.content.BroadcastReceiver
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.net.ConnectivityManager
7 | import com.android.util.NetworkUtil
8 |
9 | /**
10 | * Created by xuzhb on 2019/12/29
11 | * Desc:监听网络变化
12 | */
13 | class NetReceiver : BroadcastReceiver() {
14 |
15 | override fun onReceive(context: Context?, intent: Intent?) {
16 | if ((ConnectivityManager.CONNECTIVITY_ACTION).equals(intent?.action)) {
17 | mOnNetChangeListener?.invoke(NetworkUtil.isConnected(context!!))
18 | }
19 | }
20 |
21 | private var mOnNetChangeListener: ((isConnected: Boolean) -> Unit)? = null
22 |
23 | fun setOnNetChangeListener(listener: ((isConnected: Boolean) -> Unit)) {
24 | this.mOnNetChangeListener = listener
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/util/app/AATest/AppAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.android.util.app.AATest
2 |
3 | import android.content.Context
4 | import com.android.basicproject.R
5 | import com.android.util.app.AppInfo
6 | import com.android.widget.RecyclerView.BaseAdapter
7 | import com.android.widget.RecyclerView.ViewHolder
8 |
9 | /**
10 | * Created by xuzhb on 2020/12/3
11 | * Desc:
12 | */
13 | class AppAdapter(context: Context, list: MutableList) : BaseAdapter(context, list, R.layout.item_image_with_text) {
14 | override fun bindData(holder: ViewHolder, data: AppInfo, position: Int) {
15 | holder.setImageDrawable(R.id.item_iv, data.icon!!)
16 | .setText(R.id.item_tv, data.label)
17 | }
18 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/util/app/AppInfo.kt:
--------------------------------------------------------------------------------
1 | package com.android.util.app
2 |
3 | import android.graphics.drawable.Drawable
4 |
5 | /**
6 | * Created by xuzhb on 2020/11/17
7 | * Desc:应用信息类
8 | */
9 | data class AppInfo(
10 | val uid: Int = 0, //应用UID
11 | val label: String? = null, //应用标签,即名称
12 | val icon: Drawable? = null, //应用图片
13 | val packageName: String? = null, //应用包名
14 | val apkPath: String? = null, //应用路径
15 | val versionName: String? = null, //应用版本号
16 | val versionCode: Int = 0, //应用版本码
17 | val isSystemApp: Boolean = false //是否是系统App
18 | )
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/util/threadPool/StepThread.kt:
--------------------------------------------------------------------------------
1 | package com.android.util.threadPool
2 |
3 | import java.util.concurrent.Callable
4 |
5 | /**
6 | * Created by xuzhb on 2020/12/8
7 | * Desc:封装Callable接口
8 | */
9 | abstract class StepThread : Callable {
10 |
11 | //初始化
12 | @Throws(Exception::class)
13 | abstract fun init()
14 |
15 | //执行任务并返回最终结果
16 | @Throws(Exception::class)
17 | abstract fun execute(): V
18 |
19 | //发生异常时回调
20 | abstract fun onError(e: Exception?)
21 |
22 | //可以做一些最终的资源释放
23 | abstract fun onDestory()
24 |
25 | @Throws(Exception::class)
26 | override fun call(): V? {
27 | try {
28 | init()
29 | return execute()
30 | } catch (e: Exception) {
31 | onError(e)
32 | } finally {
33 | onDestory()
34 | }
35 | return null
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/ExpandTextView/BoldInfo.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.ExpandTextView
2 |
3 | /**
4 | * Created by xuzhb on 2024/5/22
5 | * Desc:字体加粗索引
6 | */
7 | data class BoldInfo(
8 | val startPosition: Int, //加粗起始位置
9 | val endPosition: Int //加粗结束位置
10 | ) {
11 | fun isActive(position: Int) = position in startPosition..endPosition
12 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/ExpandTextView/ColorInfo.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.ExpandTextView
2 |
3 | import androidx.annotation.ColorInt
4 |
5 | /**
6 | * Created by xuzhb on 2024/5/22
7 | * Desc:字体变色
8 | */
9 | data class ColorInfo(
10 | val startPosition: Int, //变色起始位置
11 | val endPosition: Int, //变色结束位置
12 | @ColorInt val color: Int //字体颜色
13 | ) {
14 | fun isActive(position: Int) = position in startPosition..endPosition
15 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/FloatWindow/NeedPermission/AATest/TestFloatPageTwoActivity.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission.AATest
2 |
3 | import android.os.Bundle
4 | import com.android.basicproject.databinding.ActivityCommonLayoutBinding
5 | import com.android.frame.mvc.BaseActivity
6 | import com.android.util.initCommonLayout
7 |
8 | /**
9 | * Created by xuzhb on 2021/3/30
10 | * Desc:
11 | */
12 | class TestFloatPageTwoActivity : BaseActivity() {
13 |
14 | override fun handleView(savedInstanceState: Bundle?) {
15 | initCommonLayout(this, "悬浮窗页面二", false, true, "跳转到悬浮窗页面三")
16 | binding.tv.text = "悬浮窗A不在页面二显示"
17 | }
18 |
19 | override fun initListener() {
20 | binding.btn1.setOnClickListener {
21 | startActivity(TestFloatPageThreeActivity::class.java)
22 | }
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/FloatWindow/NeedPermission/IFloatWindow.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission
2 |
3 | import android.view.View
4 |
5 | /**
6 | * Created by xuzhb on 2021/3/29
7 | * Desc:
8 | */
9 | interface IFloatWindow {
10 |
11 | fun show()
12 |
13 | fun hide()
14 |
15 | fun isShowing(): Boolean
16 |
17 | fun getX(): Int
18 |
19 | fun getY(): Int
20 |
21 | fun updateX(x: Int)
22 |
23 | /**
24 | * 更新x坐标
25 | *
26 | * @param screenType 以屏幕宽度或屏幕高度为基准
27 | * @param ratio 占比
28 | */
29 | fun updateX(@ScreenType.screenType screenType: Int, ratio: Float)
30 |
31 | fun updateY(y: Int)
32 |
33 | /**
34 | * 更新y坐标
35 | *
36 | * @param screenType 以屏幕宽度或屏幕高度为基准
37 | * @param ratio 占比
38 | */
39 | fun updateY(@ScreenType.screenType screenType: Int, ratio: Float)
40 |
41 | fun updateXY(x: Int, y: Int)
42 |
43 | fun getView(): View?
44 |
45 | //使用FloatWindow.destroy()来取消弹窗,不要手动调用下面的方法
46 | @Deprecated("Please use destroy")
47 | fun dismiss()
48 |
49 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/FloatWindow/NeedPermission/MoveType.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission
2 |
3 | import androidx.annotation.IntDef
4 |
5 | /**
6 | * Created by xuzhb on 2021/3/29
7 | * Desc:
8 | */
9 | object MoveType {
10 | const val inactive = 1 //不可移动
11 | const val active = 2 //可移动
12 | const val slide = 3 //移动松手后贴边
13 | const val back = 4 //移动松手后回到原来的位置
14 |
15 | @IntDef(inactive, active, slide, back)
16 | @kotlin.annotation.Retention(AnnotationRetention.SOURCE)
17 | internal annotation class moveType
18 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/FloatWindow/NeedPermission/OnPermissionListener.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission
2 |
3 | /**
4 | * Created by xuzhb on 2021/3/29
5 | * Desc:权限申请结果回调
6 | */
7 | interface OnPermissionListener {
8 |
9 | //授权成功
10 | fun onSuccess()
11 |
12 | //授权失败
13 | fun onFailure()
14 |
15 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/FloatWindow/NeedPermission/OnViewStateListener.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission
2 |
3 | /**
4 | * Created by xuzhb on 2021/3/29
5 | * Desc:状态改变监听
6 | */
7 | interface OnViewStateListener {
8 |
9 | fun onPositionUpdate(x: Int, y: Int)
10 |
11 | fun onShow()
12 |
13 | fun onHide()
14 |
15 | fun onDismiss()
16 |
17 | fun onMoveAnimStart()
18 |
19 | fun onMoveAnimEnd()
20 |
21 | fun onBackToDesktop()
22 |
23 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/FloatWindow/NeedPermission/ScreenType.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NeedPermission
2 |
3 | import androidx.annotation.IntDef
4 |
5 | /**
6 | * Created by xuzhb on 2021/3/29
7 | * Desc:选择以屏幕宽度或屏幕高度为基准
8 | */
9 | object ScreenType {
10 | const val width = 0
11 | const val height = 1
12 |
13 | @IntDef(width, height)
14 | @kotlin.annotation.Retention(AnnotationRetention.SOURCE)
15 | internal annotation class screenType
16 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/FloatWindow/NoPermission/MoveType.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NoPermission
2 |
3 | import androidx.annotation.IntDef
4 |
5 | /**
6 | * Created by xuzhb on 2021/3/25
7 | * Desc:移动方式
8 | */
9 | object MoveType {
10 | const val inactive = 1 //不可移动
11 | const val active = 2 //可移动
12 | const val slide = 3 //移动松手后贴边
13 | const val back = 4 //移动松手后回到原来的位置
14 |
15 | @IntDef(inactive, active, slide, back)
16 | @kotlin.annotation.Retention(AnnotationRetention.SOURCE)
17 | internal annotation class moveType
18 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/FloatWindow/NoPermission/ScreenType.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow.NoPermission
2 |
3 | import androidx.annotation.IntDef
4 |
5 | /**
6 | * Created by xuzhb on 2021/3/25
7 | * Desc:选择以屏幕宽度或屏幕高度为基准
8 | */
9 | object ScreenType {
10 | const val width = 0
11 | const val height = 1
12 |
13 | @IntDef(width, height)
14 | @kotlin.annotation.Retention(AnnotationRetention.SOURCE)
15 | internal annotation class screenType
16 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/FloatWindow/TestFloatActivity.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.FloatWindow
2 |
3 | import android.os.Bundle
4 | import com.android.basicproject.databinding.ActivityCommonLayoutBinding
5 | import com.android.frame.mvc.BaseActivity
6 | import com.android.util.initCommonLayout
7 | import com.android.widget.FloatWindow.NeedPermission.AATest.TestFloatPageOneActivity
8 | import com.android.widget.FloatWindow.NoPermission.AATest.TestFloatPageActivity
9 |
10 | /**
11 | * Created by xuzhb on 2021/3/25
12 | * Desc:
13 | */
14 | class TestFloatActivity : BaseActivity() {
15 |
16 | override fun handleView(savedInstanceState: Bundle?) {
17 | initCommonLayout(this, "悬浮窗", "申请权限", "无需权限")
18 | }
19 |
20 | override fun initListener() {
21 | binding.btn1.setOnClickListener {
22 | startActivity(TestFloatPageOneActivity::class.java)
23 | }
24 | binding.btn2.setOnClickListener {
25 | TestFloatPageActivity.start(this, 1)
26 | }
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PhotoViewer/listener/OnGestureListener.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener
2 |
3 | /**
4 | * Created by xuzhb on 2021/3/30
5 | * Desc:手势监听
6 | */
7 | interface OnGestureListener {
8 |
9 | /**
10 | * 拖动
11 | *
12 | * @param dx 水平方向上拖动的距离
13 | * @param dy 竖直方向上拖动的距离
14 | */
15 | fun onDrag(dx: Float, dy: Float)
16 |
17 | /**
18 | * 快速滑动
19 | *
20 | * @param startX 滑动起点的x坐标
21 | * @param startY 滑动起点的y坐标
22 | * @param velocityX 水平方向上滑动的速度
23 | * @param velocityY 竖直方向上滑动的速度
24 | */
25 | fun onFling(startX: Float, startY: Float, velocityX: Float, velocityY: Float)
26 |
27 | /**
28 | * 缩放
29 | *
30 | * @param scaleFactor 缩放因子
31 | * @param focusX 组成该手势的两个触点的中点的x坐标,单位是像素
32 | * @param focusY 组成该手势的两个触点的中点的y坐标,单位是像素
33 | */
34 | fun onScale(scaleFactor: Float, focusX: Float, focusY: Float)
35 |
36 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PhotoViewer/listener/OnMatrixChangedListener.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener
2 |
3 | import android.graphics.RectF
4 |
5 | /**
6 | * Created by xuzhb on 2021/3/30
7 | * Desc:View的Matrix矩阵变化监听
8 | */
9 | interface OnMatrixChangedListener {
10 |
11 | /**
12 | * 当View的边界发生变化时回调
13 | *
14 | * @param rect View的新边界
15 | */
16 | fun onMatrixChanged(rectF: RectF)
17 |
18 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PhotoViewer/listener/OnOutsidePhotoTapListener.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener
2 |
3 | import android.widget.ImageView
4 |
5 | /**
6 | * Created by xuzhb on 2021/3/30
7 | * Desc:图片外部区域点击事件监听
8 | */
9 | interface OnOutsidePhotoTapListener {
10 |
11 | /**
12 | * 点击图片外部区域时回调
13 | */
14 | fun onOutsidePhotoTap(imageView: ImageView)
15 |
16 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PhotoViewer/listener/OnPhotoTapListener.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener
2 |
3 | import android.widget.ImageView
4 |
5 | /**
6 | * Created by xuzhb on 2021/3/30
7 | * Desc:图片单击事件监听
8 | */
9 | interface OnPhotoTapListener {
10 |
11 | /**
12 | * 点击图片区域以内时回调,图片区域以外不会回调
13 | *
14 | * @param imageView 点击的图片
15 | * @param x 点击的位置x坐标
16 | * @param y 点击的位置y坐标
17 | * @param xOffset 点击的位置相对于左上角的横向偏移量,百分比形式
18 | * @param yOffset 点击的位置相对于左上角的纵向偏移量,百分比形式
19 | */
20 | fun onPhotoTap(imageView: ImageView, x: Float, y: Float, xOffset: Float, yOffset: Float)
21 |
22 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PhotoViewer/listener/OnScaleChangedListener.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener
2 |
3 | /**
4 | * Created by xuzhb on 2021/3/30
5 | * Desc:图片缩放监听
6 | */
7 | interface OnScaleChangedListener {
8 |
9 | /**
10 | * 图片缩放时回调
11 | *
12 | * @param scaleFactor 缩放因子(小于1时缩小,大于1时放大)
13 | * @param focusX 缩放焦点的x坐标
14 | * @param focusY 缩放焦点的y坐标
15 | */
16 | fun onScaleChange(scaleFactor: Float, focusX: Float, focusY: Float)
17 |
18 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PhotoViewer/listener/OnSingleFlingListener.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener
2 |
3 | import android.view.MotionEvent
4 |
5 | /**
6 | * Created by xuzhb on 2021/3/30
7 | * Desc:快速滑动监听
8 | */
9 | interface OnSingleFlingListener {
10 |
11 | /**
12 | * 快速滑动时回调
13 | *
14 | * @param event1 首次接触时的MotionEvent
15 | * @param event2 最后一次接触时的MotionEvent
16 | * @param velocityX 水平滑动的速度
17 | * @param velocityY 竖直滑动的速度
18 | */
19 | fun onFling(event1: MotionEvent, event2: MotionEvent, velocityX: Float, velocityY: Float): Boolean
20 |
21 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PhotoViewer/listener/OnViewDragListener.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener
2 |
3 | /**
4 | * Created by xuzhb on 2021/3/30
5 | * Desc:图片拖动监听
6 | */
7 | interface OnViewDragListener {
8 |
9 | /**
10 | * 拖动图片时回调,当缩放图片时不会触发次回调
11 | *
12 | * @param dx 水平方向上拖动的距离
13 | * @param dy 竖直方向上拖动的距离
14 | */
15 | fun onDrag(dx: Float, dy: Float)
16 |
17 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PhotoViewer/listener/OnViewTapListener.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.listener
2 |
3 | import android.view.View
4 |
5 | /**
6 | * Created by xuzhb on 2021/3/30
7 | * Desc:ImageView点击事件监听
8 | */
9 | interface OnViewTapListener {
10 |
11 | /**
12 | * ImageView点击时回调
13 | *
14 | * @param view 点击的ImageView
15 | * @param x 点击的X坐标
16 | * @param y 点击的Y坐标
17 | */
18 | fun onViewTap(view: View, x: Float, y: Float)
19 |
20 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PhotoViewer/widget/PhotoViewPager.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PhotoViewer.widget
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.view.MotionEvent
6 | import androidx.viewpager.widget.ViewPager
7 |
8 | /**
9 | * Created by xuzhb on 2021/3/30
10 | */
11 | class PhotoViewPager @JvmOverloads constructor(
12 | context: Context, attrs: AttributeSet? = null
13 | ) : ViewPager(context, attrs) {
14 |
15 | override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
16 | return try {
17 | super.onInterceptTouchEvent(ev)
18 | } catch (e: Exception) {
19 | false
20 | }
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PicGetterDialog/AATest/CustomPicGetterDialog.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PicGetterDialog.AATest
2 |
3 | import android.app.Dialog
4 | import com.android.basicproject.R
5 | import com.android.widget.PicGetterDialog.BasePicGetterDialog
6 | import com.android.widget.ViewHolder
7 |
8 | /**
9 | * Created by xuzhb on 2020/1/28
10 | * Desc:
11 | */
12 | class CustomPicGetterDialog : BasePicGetterDialog() {
13 |
14 | override fun getLayoutId(): Int = R.layout.dialog_custom_pic_getter
15 |
16 | override fun convertView(holder: ViewHolder, dialog: Dialog?) {
17 | holder.setOnClickListener(R.id.camera_btn) {
18 | openCamera() //拍照
19 | }
20 | holder.setOnClickListener(R.id.gallery_btn) {
21 | openGallery() //从相册选取照片
22 | }
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PicGetterDialog/OnPicGetterListener.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PicGetterDialog
2 |
3 | import android.graphics.Bitmap
4 |
5 | /**
6 | * Created by xuzhb on 2020/1/27
7 | * Desc:
8 | */
9 | interface OnPicGetterListener {
10 |
11 | /**
12 | * 图片获取成功
13 | *
14 | * @param bitmap 图片
15 | * @param picPath 图片路径
16 | */
17 | fun onSuccess(bitmap: Bitmap?, picPath: String?)
18 |
19 | /**
20 | * 图片获取失败
21 | *
22 | * @param errorMsg 错误信息
23 | */
24 | fun onFailure(errorMsg: String?)
25 |
26 |
27 | /**
28 | * 取消图片获取
29 | */
30 | fun onCancel()
31 |
32 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PicGetterDialog/PicGetterDialog.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PicGetterDialog
2 |
3 | import android.app.Dialog
4 | import com.android.basicproject.R
5 | import com.android.widget.ViewHolder
6 |
7 | /**
8 | * Created by xuzhb on 2020/1/27
9 | * Desc:拍照或从相册选取选择框
10 | */
11 | class PicGetterDialog : BasePicGetterDialog() {
12 |
13 | override fun getLayoutId(): Int = R.layout.dialog_pic_getter
14 |
15 | override fun convertView(holder: ViewHolder, dialog: Dialog?) {
16 | holder.setOnClickListener(R.id.camera_tv) {
17 | openCamera() //拍照
18 | }
19 | holder.setOnClickListener(R.id.gallery_tv) {
20 | openGallery() //从相册选取照片
21 | }
22 | holder.setOnClickListener(R.id.cancel_tv) {
23 | getDialog()?.let {
24 | onCancel(it) //取消弹窗
25 | dismiss()
26 | }
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PicGetterDialog/说明.md:
--------------------------------------------------------------------------------
1 | 集成:
2 | 1、build.gradle导入图片裁剪框架'com.yalantis:ucrop:2.2.0'
3 | 2、AndroidManifest配置相应的fileprovider和UCropActivity
4 | 3、混淆
5 | -dontwarn com.yalantis.ucrop**
6 | -keep class com.yalantis.ucrop** { *; }
7 | -keep interface com.yalantis.ucrop** { *; }
8 |
9 | 相关类:
10 | 1、dialog_pic_getter:弹窗布局
11 | 2、pic_getter_file_paths:fileprovider配置,Android 7.0以上的系统需要使用FileProvider兼容拍照
12 | 3、PicProvider:fileprovider
13 | 4、BasePicGetterDialog
14 | 5、PicGetterDialog
15 | 6、OnPicGetterListener
16 |
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PieChart/PieData.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PieChart
2 |
3 | /**
4 | * Created by xuzhb on 2019/10/15
5 | * Desc:
6 | */
7 | data class PieData(
8 | val value: Float,
9 | val color: Int,
10 | val label: String
11 | )
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PopupWindow/AATest/PopupWindowAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PopupWindow.AATest
2 |
3 | import android.content.Context
4 | import com.android.basicproject.R
5 | import com.android.widget.RecyclerView.BaseAdapter
6 | import com.android.widget.RecyclerView.ViewHolder
7 |
8 | /**
9 | * Created by xuzhb on 2019/9/1
10 | * Desc:
11 | */
12 | class PopupWindowAdapter(context: Context, list: MutableList) :
13 | BaseAdapter(context, list, R.layout.item_popup_window) {
14 |
15 | override fun bindData(holder: ViewHolder, data: String, position: Int) {
16 | holder.setText(R.id.item_tv, data)
17 | if (position == itemCount - 1) {
18 | holder.setViewGone(R.id.divider_line)
19 | } else {
20 | holder.setViewVisible(R.id.divider_line)
21 | }
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/PopupWindow/WindowHelper.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.PopupWindow
2 |
3 | import android.app.Activity
4 | import androidx.annotation.FloatRange
5 |
6 | /**
7 | * Created by xuzhb on 2019/9/3
8 | * Desc:Window辅助类,实现背景灰色效果
9 | */
10 | class WindowHelper(private var mActivity: Activity) {
11 |
12 | //设置外部区域背景透明度,0:完全不透明,1:完全透明
13 | fun setBackGroundAlpha(@FloatRange(from = 0.0, to = 1.0) alpha: Float) {
14 | val window = mActivity.window
15 | val lp = window.attributes
16 | lp.alpha = alpha
17 | window.attributes = lp
18 | }
19 |
20 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/RecyclerView/AATest/TestLoadMoreWrapper.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.RecyclerView.AATest
2 |
3 | import android.content.Context
4 | import android.widget.ImageView
5 | import com.android.base.BaseApplication
6 | import com.android.basicproject.R
7 | import com.android.frame.http.AATest.bean.NewsListBean
8 | import com.android.widget.RecyclerView.BaseAdapter
9 | import com.android.widget.RecyclerView.ViewHolder
10 | import com.bumptech.glide.Glide
11 |
12 | /**
13 | * Created by xuzhb on 2019/10/29
14 | * Desc:上拉加载更多
15 | */
16 | class TestLoadMoreWrapper(context: Context, list: MutableList) :
17 | BaseAdapter(context, list, R.layout.item_test_load_more) {
18 | override fun bindData(holder: ViewHolder, data: NewsListBean.ResultBean, position: Int) {
19 | val imageIv: ImageView = holder.getView(R.id.image_iv)!!
20 | Glide.with(BaseApplication.instance).load(data.image).into(imageIv)
21 | holder.setText(R.id.title_tv, data.title).setText(R.id.time_tv, data.passtime)
22 | }
23 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/RecyclerView/AATest/TestSingleLoadMoreAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.RecyclerView.AATest
2 |
3 | import android.content.Context
4 | import android.widget.ImageView
5 | import com.android.base.BaseApplication
6 | import com.android.basicproject.R
7 | import com.android.frame.http.AATest.bean.NewsListBean
8 | import com.android.widget.RecyclerView.LoadMoreAdapter
9 | import com.android.widget.RecyclerView.ViewHolder
10 | import com.bumptech.glide.Glide
11 |
12 | /**
13 | * Created by xuzhb on 2020/1/13
14 | * Desc:单布局上拉加载更多
15 | */
16 | class TestSingleLoadMoreAdapter(context: Context, list: MutableList) :
17 | LoadMoreAdapter(context, list, R.layout.item_test_load_more) {
18 | override fun bindData(holder: ViewHolder, data: NewsListBean.ResultBean, position: Int) {
19 | val imageIv: ImageView = holder.getView(R.id.image_iv)!!
20 | Glide.with(BaseApplication.instance).load(data.image).into(imageIv)
21 | holder.setText(R.id.title_tv, data.title).setText(R.id.time_tv, data.passtime)
22 | }
23 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/RecyclerView/AATest/entity/DateBean.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.RecyclerView.AATest.entity
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Created by xuzhb on 2020/1/15
7 | * Desc:
8 | */
9 | data class DateBean(
10 | val date: String
11 | ) : Serializable
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/RecyclerView/AATest/entity/DetailBean.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.RecyclerView.AATest.entity
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Created by xuzhb on 2019/11/17
7 | * Desc:
8 | */
9 | data class DetailBean(
10 | val detail: String,
11 | val time: String
12 | ) : Serializable
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/RecyclerView/AATest/entity/MonthBean.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.RecyclerView.AATest.entity
2 |
3 | import java.io.Serializable
4 |
5 | /**
6 | * Created by xuzhb on 2019/11/17
7 | * Desc:
8 | */
9 | data class MonthBean(
10 | val month: String,
11 | val count: String
12 | ) : Serializable
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/RecyclerView/MultiViewType.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.RecyclerView
2 |
3 | /**
4 | * Created by xuzhb on 2019/7/30
5 | * Desc:RecyclerView实现多种Item布局
6 | */
7 | interface MultiViewType {
8 |
9 | /**
10 | * 实现多种Item布局
11 | *
12 | * @param data Item对应的数据
13 | * @param position Item的位置
14 | * @param totalCount Item的总数
15 | * @return Item对应的布局类型,使用布局的id进行区分
16 | */
17 | fun getLayoutId(data: T, position: Int, totalCount: Int): Int
18 |
19 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/ScrollTextView.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget
2 |
3 | import android.content.Context
4 | import android.text.TextUtils
5 | import android.util.AttributeSet
6 | import androidx.annotation.AttrRes
7 | import androidx.appcompat.widget.AppCompatTextView
8 |
9 | /**
10 | * Created by xuzhb on 2020/1/7
11 | * Desc:TextView文字滚动显示,即跑马灯效果(不需要获取焦点)
12 | */
13 | class ScrollTextView @JvmOverloads constructor(
14 | context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttrs: Int = 0
15 | ) : AppCompatTextView(context, attrs, defStyleAttrs) {
16 |
17 | init {
18 | setSingleLine(true)
19 | ellipsize = TextUtils.TruncateAt.MARQUEE //设置跑马灯效果
20 | marqueeRepeatLimit = -1 //设置循环滚动为无限循环
21 | }
22 |
23 | override fun isFocused(): Boolean = true
24 |
25 | }
--------------------------------------------------------------------------------
/kotlin/src/main/java/com/android/widget/dialog/CommonDialog.kt:
--------------------------------------------------------------------------------
1 | package com.android.widget.dialog
2 |
3 | import androidx.annotation.LayoutRes
4 | import androidx.fragment.app.DialogFragment
5 | import com.android.widget.ViewHolder
6 |
7 | /**
8 | * Created by xuzhb on 2019/10/22
9 | * Desc:通用的Dialog,可以实现不同布局的Dialog
10 | */
11 | class CommonDialog : BaseDialog() {
12 |
13 | companion object {
14 | fun newInstance(): CommonDialog = CommonDialog()
15 | }
16 |
17 | private var mListener: ((holder: ViewHolder, dialog: DialogFragment?) -> Unit)? = null
18 |
19 | //设置dialog的布局
20 | fun setLayoutId(@LayoutRes layoutId: Int): CommonDialog {
21 | this.mLayoutId = layoutId
22 | return this
23 | }
24 |
25 | //设置事件监听
26 | fun setOnViewListener(listener: (holder: ViewHolder, dialog: DialogFragment?) -> Unit): CommonDialog {
27 | this.mListener = listener
28 | return this
29 | }
30 |
31 | override fun getLayoutId(): Int = mLayoutId
32 |
33 | override fun convertView(holder: ViewHolder, dialog: DialogFragment?) {
34 | mListener?.invoke(holder, dialog)
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/kotlin/src/main/res/layout/activity_list_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/layout/activity_test_bitmap.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
17 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/layout/activity_test_capture_gridview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
22 |
23 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/layout/activity_test_capture_listview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/layout/activity_test_capture_recyclerview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
17 |
18 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/layout/activity_test_capture_webview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/layout/activity_test_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
16 |
17 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/layout/activity_test_pie_chart.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
21 |
22 |
27 |
28 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/layout/activity_webview.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/layout/fragment_test_mvc.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/layout/fragment_test_mvc_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/layout/fragment_webview.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Kotlin
3 |
4 |
--------------------------------------------------------------------------------
/kotlin/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/kotlin/src/test/java/com/android/basicproject/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.android.basicproject
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':kotlin', ':java', ':universal'
2 |
--------------------------------------------------------------------------------
/universal/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/universal/BasicProject.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/BasicProject.jks
--------------------------------------------------------------------------------
/universal/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/universal/src/androidTest/java/com/android/universal/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.android.universal;
2 |
3 | import android.content.Context;
4 | import androidx.test.platform.app.InstrumentationRegistry;
5 | import androidx.test.ext.junit.runners.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.android.universal.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/universal/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/universal/src/main/assets/fonts/fonts.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/assets/fonts/fonts.ttf
--------------------------------------------------------------------------------
/universal/src/main/assets/test_install.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/assets/test_install.apk
--------------------------------------------------------------------------------
/universal/src/main/res/anim/alpha_in_150.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/alpha_in_300.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/alpha_out_150.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/alpha_out_300.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/scale_bottom_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/scale_bottom_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/scale_center_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/scale_center_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/scale_left_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/scale_left_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/scale_right_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/scale_right_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/scale_top_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/scale_top_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/slide_left_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/slide_left_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/slide_right_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/slide_right_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/translate_bottom_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/translate_bottom_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/translate_left_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/translate_left_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/translate_right_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/translate_right_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/translate_top_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/universal/src/main/res/anim/translate_top_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/universal/src/main/res/color/selector_tab_text_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/color/selector_toggle_button_text_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_add.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_back.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_bg.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_bitmap.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_bitmap.jpg
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_check.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_check.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_clear.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_coupon_btn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_coupon_btn.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_coupon_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_coupon_header.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_empty_data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_empty_data.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_face1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_face1.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_face2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_face2.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_face3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_face3.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_flashlight_off.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_flashlight_off.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_flashlight_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_flashlight_on.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_frame_not_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_frame_not_selected.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_frame_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_frame_selected.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_guide_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_guide_bg.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_guide_one.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_guide_one.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_guide_three.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_guide_three.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_guide_two.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_guide_two.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_letter_bubble.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_letter_bubble.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_load_empty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_load_empty.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_load_fail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_load_fail.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_load_loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_load_loading.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_more.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_more.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_msg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_msg.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_photo_close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_photo_close.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_photo_download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_photo_download.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_photo_load_fail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_photo_load_fail.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_qq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_qq.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_query.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_query.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_scan_grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_scan_grid.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_search_clear.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_search_clear.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_search_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_search_search.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_settings.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_status_bar.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_status_bar.jpeg
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_uncheck.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_uncheck.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_util_not_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_util_not_selected.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_util_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_util_selected.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_warn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_warn.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_weibo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_weibo.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_weixin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_weixin.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_widget_not_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_widget_not_selected.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable-xhdpi/ic_widget_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/drawable-xhdpi/ic_widget_selected.png
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/layer_list_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/layer_list_input_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
16 | -
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/layer_list_progress_drawable.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 | -
8 |
11 |
12 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/loading_progressbar_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/selector_bottom_frame.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/selector_bottom_util.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/selector_bottom_widget.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/selector_btn_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/selector_flash_light_switch.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/selector_gray_item_layout_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 | -
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/selector_guide_indicator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 |
10 | -
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/selector_guide_use_btn_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/selector_item_check_btn.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/selector_item_layout_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 | -
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/selector_tab_text_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/selector_toggle_button_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 | -
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_confirm_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_corners_10_solid_000000.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_corners_15_solid_ffffff.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_corners_15_solid_transparent.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_corners_17_solid_66000000.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_coupon_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_cursor_drawable.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_indicator_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_loading_btn_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_loading_dialog_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_oval_size_34_solid_66000000.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_oval_size_34_solid_db4b3c.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_photo_view_progress_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_progressbar_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_progressbar_progress.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_search_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_size_2_solid_0071ff.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/universal/src/main/res/drawable/shape_spannable_block.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/dialog_app_detail.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
20 |
21 |
26 |
27 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/dialog_custom_pic_getter.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
20 |
21 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/dialog_loading_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
17 |
18 |
26 |
27 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/fragment_test_system_widget5.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/fragment_test_system_widget6.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/fragment_test_system_widget7.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/fragment_test_system_widget8.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/item_detail.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
23 |
24 |
27 |
28 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/item_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/item_image_with_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
23 |
24 |
28 |
29 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/item_month.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
14 |
15 |
18 |
19 |
20 |
23 |
24 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/item_photo_view_pager.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/item_popup_window.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
19 |
20 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/layout_empty_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
23 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/layout_float.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
18 |
19 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/layout_image.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/layout_net_error.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
25 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/layout_popup_window_to_bottom2.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/layout_tab_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
21 |
22 |
--------------------------------------------------------------------------------
/universal/src/main/res/layout/layout_toast.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
21 |
--------------------------------------------------------------------------------
/universal/src/main/res/mipmap-hdpi/ic_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/mipmap-hdpi/ic_logo.png
--------------------------------------------------------------------------------
/universal/src/main/res/mipmap-mdpi/ic_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/mipmap-mdpi/ic_logo.png
--------------------------------------------------------------------------------
/universal/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/universal/src/main/res/mipmap-xhdpi/ic_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/mipmap-xhdpi/ic_logo.png
--------------------------------------------------------------------------------
/universal/src/main/res/mipmap-xxhdpi/ic_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/mipmap-xxhdpi/ic_logo.png
--------------------------------------------------------------------------------
/universal/src/main/res/mipmap-xxxhdpi/ic_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/mipmap-xxxhdpi/ic_logo.png
--------------------------------------------------------------------------------
/universal/src/main/res/raw/beep.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/raw/beep.mp3
--------------------------------------------------------------------------------
/universal/src/main/res/raw/notification.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuzhb24/BasicProject/5d6e0bd09391d5326c39172295fcb30186cba7d3/universal/src/main/res/raw/notification.mp3
--------------------------------------------------------------------------------
/universal/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/universal/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | #db4b3c
5 | #db4b3c
6 | #f05b48
7 |
8 |
9 | #f7f8fd
10 |
11 | #E7E8EE
12 |
13 | #ffffff
14 | #000000
15 | #333333
16 | #ee7942
17 | #a3a3a3
18 |
19 | #0875ff
20 | #097de2
21 |
22 | #e6e6e6
23 |
24 |
--------------------------------------------------------------------------------
/universal/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 0.5dp
5 |
6 | 15dp
7 |
8 | 20dp
9 |
--------------------------------------------------------------------------------
/universal/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/universal/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | universal
3 | 加载中
4 | 当前网络不可用 , 请检查你的网络设置
5 | 暂无数据
6 |
7 |
--------------------------------------------------------------------------------
/universal/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/universal/src/main/res/xml/provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
17 |
18 |
19 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/universal/src/test/java/com/android/universal/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.android.universal;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------