Repository: ittianyu/POCenter Branch: master Commit: 24f6bdb545a4 Files: 148 Total size: 292.2 KB Directory structure: gitextract_i280fmca/ ├── .gitignore ├── LICENSE ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── libs/ │ │ ├── MobCommons-2016.1222.1756.jar │ │ ├── MobTools-2016.1222.1756.jar │ │ ├── ShareSDK-Core-2.8.0.jar │ │ ├── ShareSDK-Email-2.8.0.jar │ │ ├── ShareSDK-QQ-2.8.0.jar │ │ ├── ShareSDK-Wechat-2.8.0.jar │ │ ├── ShareSDK-Wechat-Core-2.8.0.jar │ │ ├── ShareSDK-Wechat-Favorite-2.8.0.jar │ │ └── ShareSDK-Wechat-Moments-2.8.0.jar │ ├── proguard-rules.pro │ ├── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── ittianyu/ │ │ │ └── pocenter/ │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main/ │ │ │ ├── AndroidManifest.xml │ │ │ ├── assets/ │ │ │ │ └── ShareSDK.xml │ │ │ ├── java/ │ │ │ │ ├── cn/ │ │ │ │ │ └── sharesdk/ │ │ │ │ │ └── onekeyshare/ │ │ │ │ │ ├── CustomerLogo.java │ │ │ │ │ ├── OnekeyShare.java │ │ │ │ │ ├── OnekeySharePage.java │ │ │ │ │ ├── OnekeyShareTheme.java │ │ │ │ │ ├── OnekeyShareThemeImpl.java │ │ │ │ │ ├── ShareContentCustomizeCallback.java │ │ │ │ │ └── themes/ │ │ │ │ │ └── classic/ │ │ │ │ │ ├── ClassicTheme.java │ │ │ │ │ ├── EditPage.java │ │ │ │ │ ├── FriendAdapter.java │ │ │ │ │ ├── FriendListItem.java │ │ │ │ │ ├── FriendListPage.java │ │ │ │ │ ├── IndicatorView.java │ │ │ │ │ ├── PRTHeader.java │ │ │ │ │ ├── PicViewerPage.java │ │ │ │ │ ├── PlatformPage.java │ │ │ │ │ ├── PlatformPageAdapter.java │ │ │ │ │ ├── RotateImageView.java │ │ │ │ │ ├── XView.java │ │ │ │ │ ├── land/ │ │ │ │ │ │ ├── EditPageLand.java │ │ │ │ │ │ ├── FriendListPageLand.java │ │ │ │ │ │ ├── PlatformPageAdapterLand.java │ │ │ │ │ │ └── PlatformPageLand.java │ │ │ │ │ └── port/ │ │ │ │ │ ├── EditPagePort.java │ │ │ │ │ ├── FriendListPagePort.java │ │ │ │ │ ├── PlatformPageAdapterPort.java │ │ │ │ │ └── PlatformPagePort.java │ │ │ │ └── com/ │ │ │ │ └── ittianyu/ │ │ │ │ └── pocenter/ │ │ │ │ ├── common/ │ │ │ │ │ ├── api/ │ │ │ │ │ │ ├── CacheApi.java │ │ │ │ │ │ ├── RemoteApi.java │ │ │ │ │ │ └── Repertories.java │ │ │ │ │ ├── base/ │ │ │ │ │ │ ├── BaseActivity.java │ │ │ │ │ │ ├── BaseApplication.java │ │ │ │ │ │ ├── BaseContract.java │ │ │ │ │ │ ├── BaseFragment.java │ │ │ │ │ │ └── BasePresenter.java │ │ │ │ │ ├── bean/ │ │ │ │ │ │ └── ProjectBean.java │ │ │ │ │ ├── tinker/ │ │ │ │ │ │ └── FetchPatchHandler.java │ │ │ │ │ └── utils/ │ │ │ │ │ ├── CollectionUtils.java │ │ │ │ │ ├── ConfigUtils.java │ │ │ │ │ ├── RxUtils.java │ │ │ │ │ └── UnsafeOkHttpUtils.java │ │ │ │ └── features/ │ │ │ │ ├── MainActivity.java │ │ │ │ ├── SplashActivity.java │ │ │ │ ├── detail/ │ │ │ │ │ └── DetailActivity.java │ │ │ │ ├── find/ │ │ │ │ │ ├── FindAdapter.java │ │ │ │ │ ├── FindContract.java │ │ │ │ │ ├── FindFragment.java │ │ │ │ │ └── FindPresenter.java │ │ │ │ ├── home/ │ │ │ │ │ ├── HomeAdapter.java │ │ │ │ │ ├── HomeContract.java │ │ │ │ │ ├── HomeFragment.java │ │ │ │ │ └── HomePresenter.java │ │ │ │ ├── mime/ │ │ │ │ │ └── MimeFragment.java │ │ │ │ ├── search/ │ │ │ │ │ ├── SearchActivity.java │ │ │ │ │ ├── SearchAdapter.java │ │ │ │ │ ├── SearchContract.java │ │ │ │ │ └── SearchPresenter.java │ │ │ │ ├── type/ │ │ │ │ │ ├── TypeActivity.java │ │ │ │ │ ├── TypeContract.java │ │ │ │ │ └── TypePresenter.java │ │ │ │ ├── version/ │ │ │ │ │ ├── CheckVersionService.java │ │ │ │ │ ├── VersionBean.java │ │ │ │ │ └── VersionUtils.java │ │ │ │ └── wxapi/ │ │ │ │ └── WXEntryActivity.java │ │ │ └── res/ │ │ │ ├── color/ │ │ │ │ └── selector_item_color.xml │ │ │ ├── drawable/ │ │ │ │ ├── ic_about.xml │ │ │ │ ├── ic_cycle.xml │ │ │ │ ├── ic_date.xml │ │ │ │ ├── ic_empty.xml │ │ │ │ ├── ic_error.xml │ │ │ │ ├── ic_find.xml │ │ │ │ ├── ic_github.xml │ │ │ │ ├── ic_home.xml │ │ │ │ ├── ic_logo.xml │ │ │ │ ├── ic_mine.xml │ │ │ │ ├── ic_people.xml │ │ │ │ ├── ic_share.xml │ │ │ │ ├── ic_type.xml │ │ │ │ ├── ic_version_check.xml │ │ │ │ ├── selector_button.xml │ │ │ │ ├── selector_item.xml │ │ │ │ ├── selector_type.xml │ │ │ │ ├── shape_button_normal.xml │ │ │ │ ├── shape_button_pressed.xml │ │ │ │ ├── shape_drive_line.xml │ │ │ │ ├── shape_type_checked.xml │ │ │ │ ├── shape_type_normal.xml │ │ │ │ ├── ssdk_oks_classic_platform_cell_back.xml │ │ │ │ └── ssdk_oks_classic_progressbar.xml │ │ │ ├── drawable-v21/ │ │ │ │ ├── selector_button.xml │ │ │ │ └── selector_item.xml │ │ │ ├── layout/ │ │ │ │ ├── act_detail.xml │ │ │ │ ├── act_main.xml │ │ │ │ ├── act_search.xml │ │ │ │ ├── act_splash.xml │ │ │ │ ├── act_type.xml │ │ │ │ ├── frag_find.xml │ │ │ │ ├── frag_home.xml │ │ │ │ ├── frag_mime.xml │ │ │ │ ├── item_find.xml │ │ │ │ ├── item_home.xml │ │ │ │ ├── item_search.xml │ │ │ │ ├── view_empty.xml │ │ │ │ ├── view_error.xml │ │ │ │ ├── view_loading.xml │ │ │ │ ├── view_search.xml │ │ │ │ └── view_type.xml │ │ │ ├── menu/ │ │ │ │ ├── menu_detail.xml │ │ │ │ ├── menu_navigation.xml │ │ │ │ └── menu_type.xml │ │ │ ├── values/ │ │ │ │ ├── colors.xml │ │ │ │ ├── dimens.xml │ │ │ │ ├── ssdk_instapaper_strings.xml │ │ │ │ ├── ssdk_oks_color_drawables.xml │ │ │ │ ├── ssdk_oks_strings.xml │ │ │ │ ├── ssdk_strings.xml │ │ │ │ ├── strings.xml │ │ │ │ ├── styles.xml │ │ │ │ └── values.xml │ │ │ ├── values-en/ │ │ │ │ ├── ssdk_oks_strings.xml │ │ │ │ └── ssdk_strings.xml │ │ │ └── values-w820dp/ │ │ │ └── dimens.xml │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── ittianyu/ │ │ └── pocenter/ │ │ └── ExampleUnitTest.java │ └── tinkerpatch.gradle ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.iml .gradle /local.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build /captures .externalNativeBuild ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2017 ittianyu Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ ## 外包集中营 ## 整合多个软件外包平台项目信息,替你筛选优质项目 ![MIT License](https://img.shields.io/github/license/mashape/apistatus.svg) ![api 15+](https://img.shields.io/badge/API-14%2B-green.svg) ## 关于我们 ## [![天宇工作室](https://github.com/ittianyu/MobileGuard/blob/master/read_me_images/logo-transparent.png?raw=true)](http://www.ittianyu.com) ## 功能 ## - ### 首页 ### 展示你关注的外包信息,比如: 移动app、网站开发、微信/小程序。 - ### 发现 ### 展示所有的外包信息。 - ### 搜索 ### 展示标题或描述中含有指定关键词的外包信息。 ## 截图 ## ![欢迎界面](/screenshots/splash.jpg) ![主界面](/screenshots/home.jpg) ![主界面滑动](/screenshots/home_scroll.jpg) ![发现界面](/screenshots/find.jpg) ![搜索界面](/screenshots/search.jpg) ![我的界面](/screenshots/mime.jpg) ![没有数据界面](/screenshots/empty.jpg) ![错误界面](/screenshots/error.jpg) ## 下载 ## 已在 [百度手机助手](http://shouji.baidu.com/software/10867391.html)、[91市场](http://apk.91.com/Soft/Android/com.ittianyu.pocenter-1.html)、[安卓市场](http://apk.hiapk.com/appinfo/com.ittianyu.pocenter/1) 上线。 贴出二维码方便下载 ![](http://d.hiphotos.bdimg.com/wisegame/pic/item/72dfa9ec8a136327b9c91278988fa0ec08fac752.jpg) ## 技术点 ## - 框架:MVP - 网络访问:Retrofit2 + OkHttp3 - 网络缓存:RxCache - 数据及解析:Gson 解析 json - 异步框架:RxJava2 - 设计规范:Material Design - 界面布局:BottomNavigationView + ViewPager + Fragment - 第三方接入:ShareSdk、友盟 app 统计、TinkerPatch 热更新 ## 亮点 ## - ViewPager 懒加载:在 Activity 生命周期内仅加载一次,且第一次可见时加载。 - LCEE 界面逻辑:也就是加载、内容、错误、空视图。 ## 项目包结构 ## - com.ittianyu.pocenter - common            公用代码 - api               网络访问代码 - base               基类 - bean               实体类 - utils              工具类 - features           功能 - detail             详情 - find               发现 - home             主页 - mime             我的 - search              搜索 - type              标签管理 - version             版本更新 - MainActivity          主界面 - SplashActivity         欢迎界面 ## 踩坑经历 ## - 混淆:如果项目中有用到 Gson 解析数据,不要混淆实体类。最好养成用一个库,就加上一个库的混淆代码的习惯。 ## 致谢 ## 感谢工作室的 UI大大 给与了关于配色方面的建议。 ## 授权 ## MIT License Copyright (c) 2017 ittianyu Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: app/.gitignore ================================================ /build ================================================ FILE: app/build.gradle ================================================ apply plugin: 'com.android.application' android { // signingConfigs { // release { // keyAlias 'pocenter' // keyPassword 'xxx' // storeFile file('keystore.jks') // storePassword 'xxx' // } // } compileSdkVersion 25 buildToolsVersion "25.0.0" defaultConfig { applicationId "com.ittianyu.pocenter" minSdkVersion 14 targetSdkVersion 25 versionCode 1 versionName "1.0.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // signingConfig signingConfigs.release// 使用签名 } } dataBinding { enabled true } android.defaultConfig.vectorDrawables.useSupportLibrary = true // 多渠道打包 // productFlavors { // tianyu {} // productFlavors.all { flavor -> // flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name] // } // } } // TinkerPatch 相关的配置 apply from: 'tinkerpatch.gradle' dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.1.0' testCompile 'junit:junit:4.12' // leakcanary debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5' // log compile 'com.orhanobut:logger:1.15' // http compile 'com.squareup.okhttp3:okhttp:3.4.1' compile 'com.squareup.okio:okio:1.10.0' // retrofit compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:converter-gson:2.1.0' // json compile 'com.google.code.gson:gson:2.7' // RxJava2 compile 'io.reactivex.rxjava2:rxjava:2.0.0' compile 'io.reactivex.rxjava2:rxandroid:2.0.0' compile 'org.reactivestreams:reactive-streams:1.0.0' // retrofit-adapter compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' // RxCache compile 'com.github.VictorAlbertos.RxCache:runtime:1.6.9-2.x' // To use Gson compile 'com.github.VictorAlbertos.Jolyglot:gson:0.0.3' // other compile 'com.github.ittianyu:BottomNavigationViewEx:1.1.2' // bottom navigation compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.6.1' // recycler adapter compile 'com.github.ittianyu:mvp:0.0.1' // mvp compile 'com.github.githubwing:ByeBurger:1.2.3' // hide actionbar and bottom navigation compile 'com.zhy:flowlayout-lib:1.0.3' // flow tag compile 'com.victor:lib:1.0.4' // loading animation compile 'com.github.arimorty:floatingsearchview:2.0.3' // search view compile 'com.allenliu:checkversionlib:1.0.4' // check version // share sdk compile files('libs/MobCommons-2016.1222.1756.jar') compile files('libs/MobTools-2016.1222.1756.jar') compile files('libs/ShareSDK-Core-2.8.0.jar') compile files('libs/ShareSDK-Email-2.8.0.jar') compile files('libs/ShareSDK-QQ-2.8.0.jar') compile files('libs/ShareSDK-Wechat-2.8.0.jar') compile files('libs/ShareSDK-Wechat-Core-2.8.0.jar') compile files('libs/ShareSDK-Wechat-Favorite-2.8.0.jar') compile files('libs/ShareSDK-Wechat-Moments-2.8.0.jar') // share sdk end // 友盟统计 compile 'com.umeng.analytics:analytics:latest.integration' // TinkerPatch SDK compile 'com.tinkerpatch.sdk:tinkerpatch-android-sdk:1.1.0' } ================================================ FILE: app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in E:\Android\sdk/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} #http -dontwarn okhttp3.** -dontwarn okio.** -dontwarn retrofit2.Platform$Java8 #databinding -dontwarn android.databinding.** -keep class android.databinding.** { *; } -keep class android.databinding.annotationprocessor.** { *; } ##---------------Begin: proguard configuration for Gson ---------- # Gson uses generic type information stored in a class file when working with fields. Proguard # removes such information by default, so configure it to keep all of it. -keepattributes Signature # For using GSON @Expose annotation -keepattributes *Annotation* # Gson specific classes -keep class sun.misc.Unsafe { *; } #-keep class com.google.gson.stream.** { *; } # Application classes that will be serialized/deserialized over Gson -keep class com.google.gson.examples.android.model.** { *; } # Prevent proguard from stripping interface information from TypeAdapterFactory, # JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter) -keep class * implements com.google.gson.TypeAdapterFactory -keep class * implements com.google.gson.JsonSerializer -keep class * implements com.google.gson.JsonDeserializer ##---------------End: proguard configuration for Gson ---------- #友盟 -keepclassmembers class * { public (org.json.JSONObject); } -keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); } #fastjson -dontwarn com.alibaba.fastjson.** -keep class com.alibaba.fastjson.** { *; } #rx cache -dontwarn io.rx_cache.internal.** -keepclassmembers enum io.rx_cache.Source { *; } -keep class io.rx_cache2.** { *; } # bottom navigation -keep public class android.support.design.widget.BottomNavigationView { *; } -keep public class android.support.design.internal.BottomNavigationMenuView { *; } -keep public class android.support.design.internal.BottomNavigationPresenter { *; } -keep public class android.support.design.internal.BottomNavigationItemView { *; } #beans -keep public class **.*Bean {*;} #指定压缩级别 -optimizationpasses 5 #不跳过非公共的库的类成员 -dontskipnonpubliclibraryclassmembers #混淆时采用的算法 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* #把混淆类中的方法名也混淆了 -useuniqueclassmembernames #优化时允许访问并修改有修饰符的类和类的成员 -allowaccessmodification #将文件来源重命名为“SourceFile”字符串 -renamesourcefileattribute SourceFile #保留行号 -keepattributes SourceFile,LineNumberTable #保持所有实现 Serializable 接口的类成员 -keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve(); } #Fragment不需要在AndroidManifest.xml中注册,需要额外保护下 -keep public class * extends android.support.v4.app.Fragment -keep public class * extends android.app.Fragment # 保持测试相关的代码 -dontnote junit.framework.** -dontnote junit.runner.** -dontwarn android.test.** -dontwarn android.support.test.** -dontwarn org.junit.** ================================================ FILE: app/src/androidTest/java/com/ittianyu/pocenter/ExampleInstrumentedTest.java ================================================ package com.ittianyu.pocenter; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.*; /** * Instrumentation test, which will execute on an Android device. * * @see Testing documentation */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { @Test public void useAppContext() throws Exception { // Context of the app under test. Context appContext = InstrumentationRegistry.getTargetContext(); assertEquals("com.ittianyu.pocenter", appContext.getPackageName()); } } ================================================ FILE: app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: app/src/main/assets/ShareSDK.xml ================================================ ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/CustomerLogo.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare; import android.graphics.Bitmap; import android.view.View.OnClickListener; /** 九宫格自定义的图标对象 */ public class CustomerLogo { public String label; public Bitmap logo; public OnClickListener listener; } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/OnekeyShare.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare; import static com.mob.tools.utils.BitmapHelper.captureView; import java.util.ArrayList; import java.util.HashMap; import android.content.Context; import android.graphics.Bitmap; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import cn.sharesdk.framework.Platform; import cn.sharesdk.framework.PlatformActionListener; import cn.sharesdk.framework.ShareSDK; import com.mob.tools.utils.ResHelper; /** * 快捷分享的入口 *

* 通过不同的setter设置参数,然后调用{@link #show(Context)}方法启动快捷分享 */ public class OnekeyShare { private HashMap params; public OnekeyShare() { params = new HashMap(); params.put("customers", new ArrayList()); params.put("hiddenPlatforms", new HashMap()); } /** address是接收人地址,仅在信息和邮件使用,否则可以不提供 */ public void setAddress(String address) { params.put("address", address); } /** * title标题,在印象笔记、邮箱、信息、微信(包括好友、朋友圈和收藏)、 * 易信(包括好友、朋友圈)、人人网和QQ空间使用,否则可以不提供 */ public void setTitle(String title) { params.put("title", title); } /** titleUrl是标题的网络链接,仅在人人网和QQ空间使用,否则可以不提供 */ public void setTitleUrl(String titleUrl) { params.put("titleUrl", titleUrl); } /** text是分享文本,所有平台都需要这个字段 */ public void setText(String text) { params.put("text", text); } /** 获取text字段的值 */ public String getText() { return params.containsKey("text") ? String.valueOf(params.get("text")) : null; } /** imagePath是本地的图片路径,除Linked-In外的所有平台都支持这个字段 */ public void setImagePath(String imagePath) { if(!TextUtils.isEmpty(imagePath)) params.put("imagePath", imagePath); } /** imageUrl是图片的网络路径,新浪微博、人人网、QQ空间和Linked-In支持此字段 */ public void setImageUrl(String imageUrl) { if (!TextUtils.isEmpty(imageUrl)) params.put("imageUrl", imageUrl); } /** url在微信(包括好友、朋友圈收藏)和易信(包括好友和朋友圈)中使用,否则可以不提供 */ public void setUrl(String url) { params.put("url", url); } /** filePath是待分享应用程序的本地路劲,仅在微信(易信)好友和Dropbox中使用,否则可以不提供 */ public void setFilePath(String filePath) { params.put("filePath", filePath); } /** comment是我对这条分享的评论,仅在人人网和QQ空间使用,否则可以不提供 */ public void setComment(String comment) { params.put("comment", comment); } /** site是分享此内容的网站名称,仅在QQ空间使用,否则可以不提供 */ public void setSite(String site) { params.put("site", site); } /** siteUrl是分享此内容的网站地址,仅在QQ空间使用,否则可以不提供 */ public void setSiteUrl(String siteUrl) { params.put("siteUrl", siteUrl); } /** foursquare分享时的地方名 */ public void setVenueName(String venueName) { params.put("venueName", venueName); } /** foursquare分享时的地方描述 */ public void setVenueDescription(String venueDescription) { params.put("venueDescription", venueDescription); } /** 分享地纬度,新浪微博、腾讯微博和foursquare支持此字段 */ public void setLatitude(float latitude) { params.put("latitude", latitude); } /** 分享地经度,新浪微博、腾讯微博和foursquare支持此字段 */ public void setLongitude(float longitude) { params.put("longitude", longitude); } /** 是否直接分享 */ public void setSilent(boolean silent) { params.put("silent", silent); } /** 设置编辑页的初始化选中平台 */ public void setPlatform(String platform) { params.put("platform", platform); } /** 设置KakaoTalk的应用下载地址 */ public void setInstallUrl(String installurl) { params.put("installurl", installurl); } /** 设置KakaoTalk的应用打开地址 */ public void setExecuteUrl(String executeurl) { params.put("executeurl", executeurl); } /** 设置微信分享的音乐的地址 */ public void setMusicUrl(String musicUrl) { params.put("musicUrl", musicUrl); } /** 设置自定义的外部回调 */ public void setCallback(PlatformActionListener callback) { params.put("callback", callback); } /** 返回操作回调 */ public PlatformActionListener getCallback() { return ResHelper.forceCast(params.get("callback")); } /** 设置用于分享过程中,根据不同平台自定义分享内容的回调 */ public void setShareContentCustomizeCallback(ShareContentCustomizeCallback callback) { params.put("customizeCallback", callback); } /** 自定义不同平台分享不同内容的回调 */ public ShareContentCustomizeCallback getShareContentCustomizeCallback() { return ResHelper.forceCast(params.get("customizeCallback")); } /** 设置自己图标和点击事件,可以重复调用添加多次 */ public void setCustomerLogo(Bitmap logo, String label, OnClickListener ocl) { CustomerLogo cl = new CustomerLogo(); cl.logo = logo; cl.label = label; cl.listener = ocl; ArrayList customers = ResHelper.forceCast(params.get("customers")); customers.add(cl); } /** 设置一个总开关,用于在分享前若需要授权,则禁用sso功能 */ public void disableSSOWhenAuthorize() { params.put("disableSSO", true); } /** 设置视频网络地址 */ public void setVideoUrl(String url) { params.put("url", url); params.put("shareType", Platform.SHARE_VIDEO); } /** 设置编辑页面的显示模式为Dialog模式 */ @Deprecated public void setDialogMode() { params.put("dialogMode", true); } /** 添加一个隐藏的platform */ public void addHiddenPlatform(String platform) { HashMap hiddenPlatforms = ResHelper.forceCast(params.get("hiddenPlatforms")); hiddenPlatforms.put(platform, platform); } /** 设置一个将被截图分享的View , surfaceView是截不了图片的*/ public void setViewToShare(View viewToShare) { try { Bitmap bm = captureView(viewToShare, viewToShare.getWidth(), viewToShare.getHeight()); params.put("viewToShare", bm); } catch (Throwable e) { e.printStackTrace(); } } /** 腾讯微博分享多张图片 */ public void setImageArray(String[] imageArray) { params.put("imageArray", imageArray); } /** 设置在执行分享到QQ或QZone的同时,分享相同的内容腾讯微博 */ public void setShareToTencentWeiboWhenPerformingQQOrQZoneSharing() { params.put("isShareTencentWeibo", true); } /** 设置分享界面的样式,目前只有一种,不需要设置 */ public void setTheme(OnekeyShareTheme theme) { params.put("theme", theme.getValue()); } @SuppressWarnings("unchecked") public void show(Context context) { HashMap shareParamsMap = new HashMap(); shareParamsMap.putAll(params); ShareSDK.initSDK(context.getApplicationContext()); // 打开分享菜单的统计 ShareSDK.logDemoEvent(1, null); int iTheme = 0; try { iTheme = ResHelper.parseInt(String.valueOf(shareParamsMap.remove("theme"))); } catch (Throwable t) {} OnekeyShareTheme theme = OnekeyShareTheme.fromValue(iTheme); OnekeyShareThemeImpl themeImpl = theme.getImpl(); themeImpl.setShareParamsMap(shareParamsMap); themeImpl.setDialogMode(shareParamsMap.containsKey("dialogMode") ? ((Boolean) shareParamsMap.remove("dialogMode")) : false); themeImpl.setSilent(shareParamsMap.containsKey("silent") ? ((Boolean) shareParamsMap.remove("silent")) : false); themeImpl.setCustomerLogos((ArrayList) shareParamsMap.remove("customers")); themeImpl.setHiddenPlatforms((HashMap) shareParamsMap.remove("hiddenPlatforms")); themeImpl.setPlatformActionListener((PlatformActionListener) shareParamsMap.remove("callback")); themeImpl.setShareContentCustomizeCallback((ShareContentCustomizeCallback) shareParamsMap.remove("customizeCallback")); if (shareParamsMap.containsKey("disableSSO") ? ((Boolean) shareParamsMap.remove("disableSSO")) : false) { themeImpl.disableSSO(); } themeImpl.show(context.getApplicationContext()); } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/OnekeySharePage.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare; import java.util.ArrayList; import java.util.HashMap; import cn.sharesdk.framework.Platform; import cn.sharesdk.framework.Platform.ShareParams; import cn.sharesdk.framework.PlatformActionListener; import com.mob.tools.FakeActivity; /** 快捷分享的基类 */ public class OnekeySharePage extends FakeActivity { private OnekeyShareThemeImpl impl; public OnekeySharePage(OnekeyShareThemeImpl impl) { this.impl = impl; } /** 分享界面是否弹窗模式 */ protected final boolean isDialogMode() { return impl.dialogMode; } protected final HashMap getShareParamsMap() { return impl.shareParamsMap; } /** 静默分享开关(没有界面,直接分享 )*/ protected final boolean isSilent() { return impl.silent; } protected final ArrayList getCustomerLogos() { return impl.customerLogos; } protected final HashMap getHiddenPlatforms() { return impl.hiddenPlatforms; } protected final PlatformActionListener getCallback() { return impl.callback; } protected final ShareContentCustomizeCallback getCustomizeCallback() { return impl.customizeCallback; } protected final boolean isDisableSSO() { return impl.disableSSO; } protected final void shareSilently(Platform platform) { impl.shareSilently(platform); } protected final ShareParams formateShareData(Platform platform) { if (impl.formateShareData(platform)) { return impl.shareDataToShareParams(platform); } return null; } protected final boolean isUseClientToShare(Platform platform) { return impl.isUseClientToShare(platform); } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/OnekeyShareTheme.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare; import cn.sharesdk.onekeyshare.themes.classic.ClassicTheme; /** 快捷分享的主题样式 */ public enum OnekeyShareTheme { /** 九格宫的主题样式 ,对应的实现类ClassicTheme */ CLASSIC(0, new ClassicTheme()); private final int value; private final OnekeyShareThemeImpl impl; private OnekeyShareTheme(int value, OnekeyShareThemeImpl impl) { this.value = value; this.impl = impl; } public int getValue() { return value; } public OnekeyShareThemeImpl getImpl() { return impl; } public static OnekeyShareTheme fromValue(int value) { for (OnekeyShareTheme theme : OnekeyShareTheme.values()) { if (theme.value == value) { return theme; } } return CLASSIC; } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/OnekeyShareThemeImpl.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare; import java.io.File; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.HashMap; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.os.Handler.Callback; import android.os.Message; import android.text.TextUtils; import android.widget.Toast; import cn.sharesdk.framework.CustomPlatform; import cn.sharesdk.framework.Platform; import cn.sharesdk.framework.Platform.ShareParams; import cn.sharesdk.framework.PlatformActionListener; import cn.sharesdk.framework.ShareSDK; import com.mob.tools.utils.ResHelper; import com.mob.tools.utils.UIHandler; /** 快捷分享的主题样式的实现父类 */ public abstract class OnekeyShareThemeImpl implements PlatformActionListener, Callback { protected boolean dialogMode; protected HashMap shareParamsMap; protected boolean silent; protected ArrayList customerLogos; protected HashMap hiddenPlatforms; protected PlatformActionListener callback; protected ShareContentCustomizeCallback customizeCallback; protected boolean disableSSO; protected Context context; public OnekeyShareThemeImpl() { callback = this; } public final void setDialogMode(boolean dialogMode) { this.dialogMode = dialogMode; } public final void setShareParamsMap(HashMap shareParamsMap) { this.shareParamsMap = shareParamsMap; } public final void setSilent(boolean silent) { this.silent = silent; } public final void setCustomerLogos(ArrayList customerLogos) { this.customerLogos = customerLogos; } public final void setHiddenPlatforms(HashMap hiddenPlatforms) { this.hiddenPlatforms = hiddenPlatforms; } public final void setPlatformActionListener(PlatformActionListener callback) { this.callback = callback == null ? this : callback; } public final void setShareContentCustomizeCallback(ShareContentCustomizeCallback customizeCallback) { this.customizeCallback = customizeCallback; } public final void disableSSO() { disableSSO = true; } public final void show(Context context) { this.context = context; // 显示方式是由platform和silent两个字段控制的 // 如果platform设置了,则无须显示九宫格,否则都会显示; // 如果silent为true,表示不进入编辑页面,否则会进入。 if (shareParamsMap.containsKey("platform")) { String name = String.valueOf(shareParamsMap.get("platform")); Platform platform = ShareSDK.getPlatform(name); boolean isCustomPlatform = platform instanceof CustomPlatform; boolean isUseClientToShare = isUseClientToShare(platform); if (silent || isCustomPlatform || isUseClientToShare) { shareSilently(platform); } else { prepareForEditPage(platform); } } else { showPlatformPage(context); } } /** 判断指定平台是否只能使用客户端分享 */ final boolean isUseClientToShare(Platform platform) { String name = platform.getName(); if ("Wechat".equals(name) || "WechatMoments".equals(name) || "WechatFavorite".equals(name) || "ShortMessage".equals(name) || "Email".equals(name) || "Qzone".equals(name) || "QQ".equals(name) || "Pinterest".equals(name) || "Instagram".equals(name) || "Yixin".equals(name) || "YixinMoments".equals(name) || "QZone".equals(name) || "Mingdao".equals(name) || "Line".equals(name) || "KakaoStory".equals(name) || "KakaoTalk".equals(name) || "Bluetooth".equals(name) || "WhatsApp".equals(name) || "BaiduTieba".equals(name) || "Laiwang".equals(name) || "LaiwangMoments".equals(name) || "Alipay".equals(name) || "AlipayMoments".equals(name)|| "FacebookMessenger".equals(name) || "GooglePlus".equals(name) ) { return true; } else if ("Evernote".equals(name)) { if ("true".equals(platform.getDevinfo("ShareByAppClient"))) { return true; } } else if ("SinaWeibo".equals(name)) { if ("true".equals(platform.getDevinfo("ShareByAppClient"))) { Intent test = new Intent(Intent.ACTION_SEND); test.setPackage("com.sina.weibo"); test.setType("image/*"); ResolveInfo ri = platform.getContext().getPackageManager().resolveActivity(test, 0); if(ri == null) { test = new Intent(Intent.ACTION_SEND); test.setPackage("com.sina.weibog3"); test.setType("image/*"); ri = platform.getContext().getPackageManager().resolveActivity(test, 0); } return (ri != null); } } return false; } final void shareSilently(Platform platform) { if (formateShareData(platform)) { ShareParams sp = shareDataToShareParams(platform); if (sp != null) { toast("ssdk_oks_sharing"); if (customizeCallback != null) { customizeCallback.onShare(platform, sp); } if (disableSSO) { platform.SSOSetting(disableSSO); } platform.setPlatformActionListener(callback); platform.share(sp); } } } private void prepareForEditPage(Platform platform) { if (formateShareData(platform)) { ShareParams sp = shareDataToShareParams(platform); if (sp != null) { // 编辑分享内容的统计 ShareSDK.logDemoEvent(3, null); if (customizeCallback != null) { customizeCallback.onShare(platform, sp); } showEditPage(context, platform, sp); } } } final boolean formateShareData(Platform plat) { String name = plat.getName(); boolean isAlipay = "Alipay".equals(name) || "AlipayMoments".equals(name); if (isAlipay && !plat.isClientValid()) { toast("ssdk_alipay_client_inavailable"); return false; } boolean isKakaoTalk = "KakaoTalk".equals(name); if (isKakaoTalk && !plat.isClientValid()) { toast("ssdk_kakaotalk_client_inavailable"); return false; } boolean isKakaoStory = "KakaoStory".equals(name); if (isKakaoStory && !plat.isClientValid()) { toast("ssdk_kakaostory_client_inavailable"); return false; } boolean isLine = "Line".equals(name); if (isLine && !plat.isClientValid()) { toast("ssdk_line_client_inavailable"); return false; } boolean isWhatsApp = "WhatsApp".equals(name); if (isWhatsApp && !plat.isClientValid()) { toast("ssdk_whatsapp_client_inavailable"); return false; } boolean isPinterest = "Pinterest".equals(name); if (isPinterest && !plat.isClientValid()) { toast("ssdk_pinterest_client_inavailable"); return false; } if ("Instagram".equals(name) && !plat.isClientValid()) { toast("ssdk_instagram_client_inavailable"); return false; } if ("QZone".equals(name) && !plat.isClientValid()) { toast("ssdk_qq_client_inavailable"); return false; } boolean isLaiwang = "Laiwang".equals(name); boolean isLaiwangMoments = "LaiwangMoments".equals(name); if(isLaiwang || isLaiwangMoments){ if (!plat.isClientValid()) { toast("ssdk_laiwang_client_inavailable"); return false; } } boolean isYixin = "YixinMoments".equals(name) || "Yixin".equals(name); if (isYixin && !plat.isClientValid()) { toast("ssdk_yixin_client_inavailable"); return false; } boolean isWechat = "WechatFavorite".equals(name) || "Wechat".equals(name) || "WechatMoments".equals(name); if (isWechat && !plat.isClientValid()) { toast("ssdk_wechat_client_inavailable"); return false; } if ("FacebookMessenger".equals(name) && !plat.isClientValid()) { toast("ssdk_facebookmessenger_client_inavailable"); return false; } if (!shareParamsMap.containsKey("shareType")) { int shareType = Platform.SHARE_TEXT; String imagePath = String.valueOf(shareParamsMap.get("imagePath")); if (imagePath != null && (new File(imagePath)).exists()) { shareType = Platform.SHARE_IMAGE; if (imagePath.endsWith(".gif") && isWechat) { shareType = Platform.SHARE_EMOJI; } else if (shareParamsMap.containsKey("url") && !TextUtils.isEmpty(shareParamsMap.get("url").toString())) { shareType = Platform.SHARE_WEBPAGE; if (shareParamsMap.containsKey("musicUrl") && !TextUtils.isEmpty(shareParamsMap.get("musicUrl").toString()) && isWechat) { shareType = Platform.SHARE_MUSIC; } } } else { Bitmap viewToShare = ResHelper.forceCast(shareParamsMap.get("viewToShare")); if (viewToShare != null && !viewToShare.isRecycled()) { shareType = Platform.SHARE_IMAGE; if (shareParamsMap.containsKey("url") && !TextUtils.isEmpty(shareParamsMap.get("url").toString())) { shareType = Platform.SHARE_WEBPAGE; if (shareParamsMap.containsKey("musicUrl") && !TextUtils.isEmpty(shareParamsMap.get("musicUrl").toString()) && isWechat) { shareType = Platform.SHARE_MUSIC; } } } else { Object imageUrl = shareParamsMap.get("imageUrl"); if (imageUrl != null && !TextUtils.isEmpty(String.valueOf(imageUrl))) { shareType = Platform.SHARE_IMAGE; if (String.valueOf(imageUrl).endsWith(".gif") && isWechat) { shareType = Platform.SHARE_EMOJI; } else if (shareParamsMap.containsKey("url") && !TextUtils.isEmpty(shareParamsMap.get("url").toString())) { shareType = Platform.SHARE_WEBPAGE; if (shareParamsMap.containsKey("musicUrl") && !TextUtils.isEmpty(shareParamsMap.get("musicUrl").toString()) && isWechat) { shareType = Platform.SHARE_MUSIC; } } } } } shareParamsMap.put("shareType", shareType); } return true; } final ShareParams shareDataToShareParams(Platform plat) { if (plat == null || shareParamsMap == null) { toast("ssdk_oks_share_failed"); return null; } try { String imagePath = ResHelper.forceCast(shareParamsMap.get("imagePath")); Bitmap viewToShare = ResHelper.forceCast(shareParamsMap.get("viewToShare")); if (TextUtils.isEmpty(imagePath) && viewToShare != null && !viewToShare.isRecycled()) { String path = ResHelper.getCachePath(plat.getContext(), "screenshot"); File ss = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg"); FileOutputStream fos = new FileOutputStream(ss); viewToShare.compress(CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); shareParamsMap.put("imagePath", ss.getAbsolutePath()); } } catch (Throwable t) { t.printStackTrace(); toast("ssdk_oks_share_failed"); return null; } return new ShareParams(shareParamsMap); } private void toast(final String resOrName) { UIHandler.sendEmptyMessage(0, new Callback() { public boolean handleMessage(Message msg) { int resId = ResHelper.getStringRes(context, resOrName); if (resId > 0) { Toast.makeText(context, resId, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, resOrName, Toast.LENGTH_SHORT).show(); } return false; } }); } protected abstract void showPlatformPage(Context context); protected abstract void showEditPage(Context context, Platform platform, ShareParams sp); public final void onComplete(Platform platform, int action, HashMap res) { Message msg = new Message(); msg.arg1 = 1; msg.arg2 = action; msg.obj = platform; UIHandler.sendMessage(msg, this); } public final void onError(Platform platform, int action, Throwable t) { t.printStackTrace(); Message msg = new Message(); msg.arg1 = 2; msg.arg2 = action; msg.obj = t; UIHandler.sendMessage(msg, this); // 分享失败的统计 ShareSDK.logDemoEvent(4, platform); } public final void onCancel(Platform platform, int action) { Message msg = new Message(); msg.arg1 = 3; msg.arg2 = action; msg.obj = platform; UIHandler.sendMessage(msg, this); // 分享失败的统计 ShareSDK.logDemoEvent(5, platform); } public final boolean handleMessage(Message msg) { switch (msg.arg1) { case 1: { // 成功 int resId = ResHelper.getStringRes(context, "ssdk_oks_share_completed"); if (resId > 0) { toast(context.getString(resId)); } } break; case 2: { // 失败 String expName = msg.obj.getClass().getSimpleName(); if ("WechatClientNotExistException".equals(expName) || "WechatTimelineNotSupportedException".equals(expName) || "WechatFavoriteNotSupportedException".equals(expName)) { toast("ssdk_wechat_client_inavailable"); } else if ("GooglePlusClientNotExistException".equals(expName)) { toast("ssdk_google_plus_client_inavailable"); } else if ("QQClientNotExistException".equals(expName)) { toast("ssdk_qq_client_inavailable"); } else if ("YixinClientNotExistException".equals(expName) || "YixinTimelineNotSupportedException".equals(expName)) { toast("ssdk_yixin_client_inavailable"); } else if ("KakaoTalkClientNotExistException".equals(expName)) { toast("ssdk_kakaotalk_client_inavailable"); } else if ("KakaoStoryClientNotExistException".equals(expName)) { toast("ssdk_kakaostory_client_inavailable"); } else if("WhatsAppClientNotExistException".equals(expName)){ toast("ssdk_whatsapp_client_inavailable"); } else if("FacebookMessengerClientNotExistException".equals(expName)){ toast("ssdk_facebookmessenger_client_inavailable"); } else { toast("ssdk_oks_share_failed"); } } break; case 3: { // 取消 toast("ssdk_oks_share_canceled"); } break; } return false; } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/ShareContentCustomizeCallback.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare; import cn.sharesdk.framework.Platform; import cn.sharesdk.framework.Platform.ShareParams; /** 自定义不同平台分享不同内容的接口 */ public interface ShareContentCustomizeCallback { public void onShare(Platform platform, ShareParams paramsToShare); } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/ClassicTheme.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic; import android.content.Context; import android.content.res.Configuration; import cn.sharesdk.framework.Platform; import cn.sharesdk.framework.Platform.ShareParams; import cn.sharesdk.onekeyshare.OnekeyShareThemeImpl; import cn.sharesdk.onekeyshare.themes.classic.land.EditPageLand; import cn.sharesdk.onekeyshare.themes.classic.land.PlatformPageLand; import cn.sharesdk.onekeyshare.themes.classic.port.EditPagePort; import cn.sharesdk.onekeyshare.themes.classic.port.PlatformPagePort; /** 九宫格经典主题样式的实现类*/ public class ClassicTheme extends OnekeyShareThemeImpl { /** 展示平台列表*/ protected void showPlatformPage(Context context) { PlatformPage page; int orientation = context.getResources().getConfiguration().orientation; if (orientation == Configuration.ORIENTATION_PORTRAIT) { page = new PlatformPagePort(this); } else { page = new PlatformPageLand(this); } page.show(context, null); } /** 展示编辑界面*/ protected void showEditPage(Context context, Platform platform, ShareParams sp) { EditPage page; int orientation = context.getResources().getConfiguration().orientation; if (orientation == Configuration.ORIENTATION_PORTRAIT) { page = new EditPagePort(this); } else { page = new EditPageLand(this); } page.setPlatform(platform); page.setShareParams(sp); page.show(context, null); } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/EditPage.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic; import java.util.ArrayList; import java.util.HashMap; import android.app.Activity; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.drawable.ColorDrawable; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import cn.sharesdk.framework.Platform; import cn.sharesdk.framework.Platform.ShareParams; import cn.sharesdk.framework.ShareSDK; import cn.sharesdk.onekeyshare.OnekeySharePage; import cn.sharesdk.onekeyshare.OnekeyShareThemeImpl; import cn.sharesdk.onekeyshare.themes.classic.land.FriendListPageLand; import cn.sharesdk.onekeyshare.themes.classic.port.FriendListPagePort; import com.mob.tools.gui.AsyncImageView; import com.mob.tools.utils.DeviceHelper; import com.mob.tools.utils.ResHelper; public class EditPage extends OnekeySharePage implements OnClickListener, TextWatcher, Runnable { private OnekeyShareThemeImpl impl; protected Platform platform; protected ShareParams sp; protected LinearLayout llPage; protected RelativeLayout rlTitle; protected ScrollView svContent; protected EditText etContent; protected TextView tvCancel; protected TextView tvShare; protected RelativeLayout rlThumb; /** 异步加载图片的控件 */ protected AsyncImageView aivThumb; protected XView xvRemove; protected LinearLayout llBottom; protected TextView tvAt; protected TextView tvTextCouter; protected Bitmap thumb; protected int maxBodyHeight; public EditPage(OnekeyShareThemeImpl impl) { super(impl); this.impl = impl; } public void setPlatform(Platform platform) { this.platform = platform; } public void setShareParams(ShareParams sp) { this.sp = sp; } public void setActivity(Activity activity) { super.setActivity(activity); if (isDialogMode()) { System.err.println("Theme classic does not support dialog mode!"); // activity.setTheme(android.R.style.Theme_Dialog); // activity.requestWindowFeature(Window.FEATURE_NO_TITLE); // if (Build.VERSION.SDK_INT >= 11) { // try { // ReflectHelper.invokeInstanceMethod(activity, "setFinishOnTouchOutside", false); // } catch (Throwable e) {} // } } activity.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); } public void onCreate() { activity.getWindow().setBackgroundDrawable(new ColorDrawable(0xfff3f3f3)); } /** 取消分享时,执行的方法 */ private void cancelAndFinish() { // 分享失败的统计 ShareSDK.logDemoEvent(5, platform); finish(); } /** 执行分享时的方法 */ private void shareAndFinish() { int resId = ResHelper.getStringRes(activity, "ssdk_oks_sharing"); if (resId > 0) { Toast.makeText(activity, resId, Toast.LENGTH_SHORT).show(); } if (isDisableSSO()) { platform.SSOSetting(true); } platform.setPlatformActionListener(getCallback()); platform.share(sp); finish(); } /** 编辑界面,显示的图片 */ private void showThumb(Bitmap pic) { PicViewerPage page = new PicViewerPage(impl); page.setImageBitmap(pic); page.show(activity, null); } private void removeThumb() { sp.setImageArray(null); sp.setImageData(null); sp.setImagePath(null); sp.setImageUrl(null); } /** @ 好友时,展示的好友列表 */ private void showFriendList() { FriendListPage page; int orientation = activity.getResources().getConfiguration().orientation; if (orientation == Configuration.ORIENTATION_PORTRAIT) { page = new FriendListPagePort(impl); } else { page = new FriendListPageLand(impl); } page.setPlatform(platform); page.showForResult(platform.getContext(), null, this); } public void onResult(HashMap data) { String atText = getJoinSelectedUser(data); if(!TextUtils.isEmpty(atText)) { etContent.append(atText); } } private String getJoinSelectedUser(HashMap data) { if (data != null && data.containsKey("selected")) { @SuppressWarnings("unchecked") ArrayList selected = (ArrayList) data.get("selected"); String platform = ((Platform)data.get("platform")).getName(); if("FacebookMessenger".equals(platform)) { return null; } StringBuilder sb = new StringBuilder(); for (String sel : selected) { sb.append('@').append(sel).append(' '); } return sb.toString(); } return null; } protected boolean isShowAtUserLayout(String platformName) { return "SinaWeibo".equals(platformName) || "TencentWeibo".equals(platformName) || "Facebook".equals(platformName) || "Twitter".equals(platformName); } public void onClick(View v) { if (v.equals(tvCancel)) { cancelAndFinish(); } else if (v.equals(tvShare)) { sp.setText(etContent.getText().toString().trim()); shareAndFinish(); } else if (v.equals(aivThumb)) { showThumb(thumb); } else if (v.equals(xvRemove)) { maxBodyHeight = 0; rlThumb.setVisibility(View.GONE); llPage.measure(0, 0); onTextChanged(etContent.getText(), 0, 0, 0); removeThumb(); } else if (v.equals(tvAt)) { showFriendList(); } } public void onTextChanged(CharSequence s, int start, int before, int count) { tvTextCouter.setText(String.valueOf(s.length())); if (maxBodyHeight == 0) { maxBodyHeight = llPage.getHeight() - rlTitle.getHeight() - llBottom.getHeight(); } if (maxBodyHeight > 0) { svContent.post(this); } } /** 动态适配编辑界面的高度 */ public void run() { int height = svContent.getChildAt(0).getHeight(); RelativeLayout.LayoutParams lp = ResHelper.forceCast(svContent.getLayoutParams()); if (height > maxBodyHeight && lp.height != maxBodyHeight) { lp.height = maxBodyHeight; svContent.setLayoutParams(lp); } else if (height < maxBodyHeight && lp.height == maxBodyHeight) { lp.height = LayoutParams.WRAP_CONTENT; svContent.setLayoutParams(lp); } } public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onPause() { DeviceHelper.getInstance(activity).hideSoftInput(getContentView()); super.onPause(); } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/FriendAdapter.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic; import java.util.ArrayList; import java.util.HashMap; import android.graphics.drawable.ColorDrawable; import android.os.Handler.Callback; import android.os.Message; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView.OnItemClickListener; import android.widget.LinearLayout; import cn.sharesdk.framework.Platform; import cn.sharesdk.framework.PlatformActionListener; import com.mob.tools.gui.PullToRequestListAdapter; import com.mob.tools.gui.PullToRequestView; import com.mob.tools.utils.UIHandler; /** 好友列表的适配器 */ public class FriendAdapter extends PullToRequestListAdapter implements PlatformActionListener { private FriendListPage activity; private boolean hasNext; private Platform platform; /** 请求好友列表时,每页15个 */ private final int pageCount = 15; /** 当前的好友列表是第几页 */ private int curPage; /** 好友列表数据 */ private ArrayList follows; /** 判断当前的好友列表数据与请求的新数据是否有重复 */ private HashMap map; /** 好友列表的头部View */ private PRTHeader llHeader; /** 根据设计,按照比例来布局,以此来适配所有手机 */ private float ratio; public FriendAdapter(FriendListPage activity, PullToRequestView view) { super(view); this.activity = activity; curPage = -1; hasNext = true; map = new HashMap(); follows = new ArrayList(); getListView().setDivider(new ColorDrawable(0xffeaeaea)); } public void setRatio(float ratio) { this.ratio = ratio; getListView().setDividerHeight((int) (ratio < 1 ? 1 : ratio)); } public void setOnItemClickListener(OnItemClickListener listener) { getListView().setOnItemClickListener(listener); } public void setPlatform(Platform platform) { this.platform = platform; platform.setPlatformActionListener(this); } private void next() { if (hasNext) { platform.listFriend(pageCount, curPage + 1, null); } } public void onComplete(Platform plat, int action, HashMap res) { final FollowersResult followersResult = parseFollowers(platform.getName(), res, map); if (followersResult == null) { UIHandler.sendEmptyMessage(0, new Callback() { public boolean handleMessage(Message msg) { notifyDataSetChanged(); return false; } }); return; } hasNext = followersResult.hasNextPage; if (followersResult.list != null && followersResult.list.size() > 0) { curPage++; Message msg = new Message(); msg.what = 1; msg.obj = followersResult.list; UIHandler.sendMessage(msg, new Callback() { public boolean handleMessage(Message msg) { if (curPage <= 0) { follows.clear(); } follows.addAll(followersResult.list); notifyDataSetChanged(); return false; } }); } } private FollowersResult parseFollowers(String platform, HashMap res, HashMap uidMap) { if (res == null || res.size() <= 0) { return null; } boolean hasNext = false; ArrayList data = new ArrayList(); if ("SinaWeibo".equals(platform)) { // users[id, name, description] @SuppressWarnings("unchecked") ArrayList> users = (ArrayList>) res.get("users"); for (HashMap user : users) { String uid = String.valueOf(user.get("id")); if (!uidMap.containsKey(uid)) { Following following = new Following(); following.uid = uid; following.screenName = String.valueOf(user.get("name")); following.description = String.valueOf(user.get("description")); following.icon = String.valueOf(user.get("profile_image_url")); following.atName = following.screenName; uidMap.put(following.uid, true); data.add(following); } } hasNext = (Integer) res.get("total_number") > uidMap.size(); } else if ("TencentWeibo".equals(platform)) { hasNext = ((Integer)res.get("hasnext") == 0); // info[nick, name, tweet[text]] @SuppressWarnings("unchecked") ArrayList> infos = (ArrayList>) res.get("info"); for (HashMap info : infos) { String uid = String.valueOf(info.get("name")); if (!uidMap.containsKey(uid)) { Following following = new Following(); following.screenName = String.valueOf(info.get("nick")); following.uid = uid; following.atName = uid; @SuppressWarnings("unchecked") ArrayList> tweets = (ArrayList>) info.get("tweet"); for (HashMap tweet : tweets) { following.description = String.valueOf(tweet.get("text")); break; } following.icon = String.valueOf(info.get("head")) + "/100"; uidMap.put(following.uid, true); data.add(following); } } } else if ("Facebook".equals(platform)) { // data[id, name] @SuppressWarnings("unchecked") ArrayList> datas = (ArrayList>) res.get("data"); for (HashMap d : datas) { String uid = String.valueOf(d.get("id")); if (!uidMap.containsKey(uid)) { Following following = new Following(); following.uid = uid; following.atName = "["+uid+"]"; following.screenName = String.valueOf(d.get("name")); @SuppressWarnings("unchecked") HashMap picture = (HashMap) d.get("picture"); if (picture != null) { @SuppressWarnings("unchecked") HashMap pData = (HashMap) picture.get("data"); following.icon = String.valueOf(pData.get("url")); } uidMap.put(following.uid, true); data.add(following); } } @SuppressWarnings("unchecked") HashMap paging = (HashMap) res.get("paging"); hasNext = paging.containsKey("next"); } else if ("Twitter".equals(platform)) { // users[screen_name, name, description] @SuppressWarnings("unchecked") ArrayList> users = (ArrayList>) res.get("users"); for (HashMap user : users) { String uid = String.valueOf(user.get("screen_name")); if (!uidMap.containsKey(uid)) { Following following = new Following(); following.uid = uid; following.atName = uid; following.screenName = String.valueOf(user.get("name")); following.description = String.valueOf(user.get("description")); following.icon = String.valueOf(user.get("profile_image_url")); uidMap.put(following.uid, true); data.add(following); } } } FollowersResult ret = new FollowersResult(); ret.list = data; ret.hasNextPage = hasNext; return ret; } public void onError(Platform plat, int action, Throwable t) { t.printStackTrace(); } public void onCancel(Platform plat, int action) { UIHandler.sendEmptyMessage(0, new Callback() { public boolean handleMessage(Message msg) { activity.finish(); return false; } }); } public Following getItem(int position) { return follows.get(position); } public long getItemId(int position) { return position; } public int getCount() { return follows == null ? 0 : follows.size(); } public View getHeaderView() { if (llHeader == null) { llHeader = new PRTHeader(getContext()); } return llHeader; } public void onPullDown(int percent) { llHeader.onPullDown(percent); } public void onRefresh() { llHeader.onRequest(); curPage = -1; hasNext = true; map.clear(); next(); } public void onReversed() { llHeader.reverse(); } public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { FriendListItem llItem = new FriendListItem(parent.getContext(), ratio); convertView = llItem; } FriendListItem llItem = (FriendListItem) convertView; llItem.update(getItem(position), isFling()); if (position == getCount() - 1) { next(); } return convertView; } public static class Following { public boolean checked; public String screenName; public String description; public String uid; public String icon; //@Name 用于微博等提示或关联某个人 public String atName; } private static class FollowersResult { public ArrayList list; public boolean hasNextPage = false; } public View getFooterView() { LinearLayout footerView = new LinearLayout(getContext()); footerView.setMinimumHeight(10); return footerView; } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/FriendListItem.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.TypedValue; import android.view.Gravity; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import cn.sharesdk.onekeyshare.themes.classic.FriendAdapter.Following; import com.mob.tools.gui.AsyncImageView; import com.mob.tools.gui.BitmapProcessor; import com.mob.tools.utils.ResHelper; /** 好友列表的item */ public class FriendListItem extends LinearLayout { private static final int DESIGN_AVATAR_WIDTH = 64; private static final int DESIGN_AVATAR_PADDING = 24; private static final int DESIGN_ITEM_HEIGHT = 96; private static final int DESIGN_ITEM_PADDING = 20; private ImageView ivCheck; private AsyncImageView aivIcon; private TextView tvName; /** 好友列表中,被选中的checkbox图标 */ private Bitmap bmChd; /** 好友列表中,没选中的checkbox图标 */ private Bitmap bmUnch; public FriendListItem(Context context, float ratio) { super(context); int itemPadding = (int) (ratio * DESIGN_ITEM_PADDING); setPadding(itemPadding, 0, itemPadding, 0); setMinimumHeight((int) (ratio * DESIGN_ITEM_HEIGHT)); setBackgroundColor(0xffffffff); ivCheck = new ImageView(context); LayoutParams lp = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp.gravity = Gravity.CENTER_VERTICAL; addView(ivCheck, lp); aivIcon = new AsyncImageView(context); int avatarWidth = (int) (ratio * DESIGN_AVATAR_WIDTH); lp = new LayoutParams(avatarWidth, avatarWidth); lp.gravity = Gravity.CENTER_VERTICAL; int avatarMargin = (int) (ratio * DESIGN_AVATAR_PADDING); lp.setMargins(avatarMargin, 0, avatarMargin, 0); addView(aivIcon, lp); tvName = new TextView(context); tvName.setTextColor(0xff000000); tvName.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); tvName.setSingleLine(); lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp.gravity = Gravity.CENTER_VERTICAL; lp.weight = 1; addView(tvName, lp); int resId = ResHelper.getBitmapRes(context, "ssdk_oks_classic_check_checked"); if (resId > 0) { bmChd = BitmapFactory.decodeResource(context.getResources(), resId); } resId = ResHelper.getBitmapRes(getContext(), "ssdk_oks_classic_check_default"); if (resId > 0) { bmUnch = BitmapFactory.decodeResource(context.getResources(), resId); } } public void update(Following following, boolean fling) { tvName.setText(following.screenName); ivCheck.setImageBitmap(following.checked ? bmChd : bmUnch); if (aivIcon != null) { if (fling) { Bitmap bm = BitmapProcessor.getBitmapFromCache(following.icon); if (bm != null && !bm.isRecycled()) { aivIcon.setImageBitmap(bm); } else { aivIcon.execute(null, 0); } } else { aivIcon.execute(following.icon, 0); } } } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/FriendListPage.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic; import java.util.ArrayList; import java.util.HashMap; import android.graphics.drawable.ColorDrawable; import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import cn.sharesdk.framework.Platform; import cn.sharesdk.onekeyshare.OnekeySharePage; import cn.sharesdk.onekeyshare.OnekeyShareThemeImpl; import cn.sharesdk.onekeyshare.themes.classic.FriendAdapter.Following; import com.mob.tools.gui.PullToRequestView; import com.mob.tools.utils.ResHelper; /** 编辑界面,@好友时,弹出的好友列表 */ public abstract class FriendListPage extends OnekeySharePage implements OnClickListener, OnItemClickListener { private static final int DESIGN_LEFT_PADDING = 40; private Platform platform; private LinearLayout llPage; private RelativeLayout rlTitle; private TextView tvCancel; private TextView tvConfirm; private FriendAdapter adapter; private int lastPosition = -1; /** 展示好友列表时,已选择要‘@’的好友个数 */ private int checkNum = 0; public FriendListPage(OnekeyShareThemeImpl impl) { super(impl); } public void setPlatform(Platform platform) { this.platform = platform; } public void onCreate() { activity.getWindow().setBackgroundDrawable(new ColorDrawable(0xfff3f3f3)); llPage = new LinearLayout(activity); llPage.setOrientation(LinearLayout.VERTICAL); activity.setContentView(llPage); rlTitle = new RelativeLayout(activity); float ratio = getRatio(); int titleHeight = (int) (getDesignTitleHeight() * ratio); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, titleHeight); llPage.addView(rlTitle, lp); initTitle(rlTitle, ratio); View line = new View(activity); LinearLayout.LayoutParams lpline = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, (int) (ratio < 1 ? 1 : ratio)); line.setBackgroundColor(0xffdad9d9); llPage.addView(line, lpline); FrameLayout flPage = new FrameLayout(getContext()); LinearLayout.LayoutParams lpFl = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); lpFl.weight = 1; flPage.setLayoutParams(lpFl); llPage.addView(flPage); // 关注(或朋友)列表 PullToRequestView followList = new PullToRequestView(getContext()); FrameLayout.LayoutParams lpLv = new FrameLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); followList.setLayoutParams(lpLv); flPage.addView(followList); adapter = new FriendAdapter(this, followList); adapter.setPlatform(platform); adapter.setRatio(ratio); adapter.setOnItemClickListener(this); followList.setAdapter(adapter); // 请求数据 followList.performPullingDown(true); } protected abstract float getRatio(); protected abstract int getDesignTitleHeight(); private void initTitle(RelativeLayout rlTitle, float ratio) { tvCancel = new TextView(activity); tvCancel.setTextColor(0xff3b3b3b); tvCancel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); tvCancel.setGravity(Gravity.CENTER); int resId = ResHelper.getStringRes(activity, "ssdk_oks_cancel"); if (resId > 0) { tvCancel.setText(resId); } int padding = (int) (DESIGN_LEFT_PADDING * ratio); tvCancel.setPadding(padding, 0, padding, 0); RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); rlTitle.addView(tvCancel, lp); tvCancel.setOnClickListener(this); TextView tvTitle = new TextView(activity); tvTitle.setTextColor(0xff3b3b3b); tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22); tvTitle.setGravity(Gravity.CENTER); resId = ResHelper.getStringRes(activity, "ssdk_oks_contacts"); if (resId > 0) { tvTitle.setText(resId); } lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); lp.addRule(RelativeLayout.CENTER_IN_PARENT); rlTitle.addView(tvTitle, lp); tvConfirm = new TextView(activity); tvConfirm.setTextColor(0xffff6d11); tvConfirm.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); tvConfirm.setGravity(Gravity.CENTER); resId = ResHelper.getStringRes(activity, "ssdk_oks_confirm"); if (resId > 0) { tvConfirm.setText(resId); } tvConfirm.setPadding(padding, 0, padding, 0); lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); rlTitle.addView(tvConfirm, lp); tvConfirm.setOnClickListener(this); } public void onClick(View v) { if (v.equals(tvCancel)) { finish(); } else { ArrayList selected = new ArrayList(); for (int i = 0, size = adapter.getCount(); i < size; i++) { if (adapter.getItem(i).checked) { selected.add(adapter.getItem(i).atName); } } HashMap res = new HashMap(); res.put("selected", selected); res.put("platform", platform); setResult(res); finish(); } } public void onItemClick(AdapterView parent, View view, int position, long id) { if ("FacebookMessenger".equals(platform.getName())) { if(lastPosition >= 0) { Following lastFollwing = adapter.getItem(lastPosition); lastFollwing.checked = false; } lastPosition = position; } Following following = adapter.getItem(position); following.checked = !following.checked; if(following.checked) { checkNum++; } else { checkNum--; } updateConfirmView(); adapter.notifyDataSetChanged(); } private void updateConfirmView() { int resId = ResHelper.getStringRes(activity, "ssdk_oks_confirm"); String confirm = "Confirm"; if(resId > 0) { confirm = getContext().getResources().getString(resId); } if(checkNum == 0) { tvConfirm.setText(confirm); } else if(checkNum > 0) { tvConfirm.setText(confirm + "(" + checkNum + ")"); } } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/IndicatorView.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.view.View; /** 九宫格滑动时,下面显示的圆圈 */ public class IndicatorView extends View { private static final int DESIGN_INDICATOR_RADIUS = 6; private static final int DESIGN_INDICATOR_DISTANCE = 14; private static final int DESIGN_BOTTOM_HEIGHT = 52; /** 九格宫有多少页数 */ private int count; /** 当前显示的是九格宫中的第几页 */ private int current; public IndicatorView(Context context) { super(context); } public void setScreenCount(int count) { this.count = count; } public void onScreenChange(int currentScreen, int lastScreen) { if (currentScreen != current) { current = currentScreen; postInvalidate(); } } protected void onDraw(Canvas canvas) { if (count <= 1) { this.setVisibility(View.GONE); return; } float height = getHeight(); float radius = height * DESIGN_INDICATOR_RADIUS / DESIGN_BOTTOM_HEIGHT; float distance = height * DESIGN_INDICATOR_DISTANCE / DESIGN_BOTTOM_HEIGHT; float windowWidth = radius * 2 * count + distance * (count - 1); float left = (getWidth() - windowWidth) / 2; float cy = height / 2; canvas.drawColor(0xffffffff); Paint paint = new Paint(); paint.setAntiAlias(true); for (int i = 0; i < count; i++) { if (i == current) { paint.setColor(0xff5d71a0); } else { paint.setColor(0xffafb1b7); } float cx = left + (radius * 2 + distance) * i; canvas.drawCircle(cx, cy, radius, paint); } } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/PRTHeader.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic; import android.content.Context; import android.graphics.drawable.Drawable; import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import com.mob.tools.utils.ResHelper; /** 下拉刷新的头部控件 */ public class PRTHeader extends LinearLayout { private static final int DESIGN_SCREEN_WIDTH = 720; private static final int DESIGN_AVATAR_WIDTH = 64; private static final int DESIGN_AVATAR_PADDING = 24; private TextView tvHeader; private RotateImageView ivArrow; private ProgressBar pbRefreshing; public PRTHeader(Context context) { super(context); int[] size = ResHelper.getScreenSize(context); float screenWidth = size[0] < size[1] ? size[0] : size[1]; float ratio = screenWidth / DESIGN_SCREEN_WIDTH; setOrientation(VERTICAL); LinearLayout llInner = new LinearLayout(context); LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp.gravity = Gravity.CENTER_HORIZONTAL; addView(llInner, lp); ivArrow = new RotateImageView(context); int resId = ResHelper.getBitmapRes(context, "ssdk_oks_ptr_ptr"); if (resId > 0) { ivArrow.setImageResource(resId); } int avatarWidth = (int) (ratio * DESIGN_AVATAR_WIDTH); lp = new LayoutParams(avatarWidth, avatarWidth); lp.gravity = Gravity.CENTER_VERTICAL; int avataPadding = (int) (ratio * DESIGN_AVATAR_PADDING); lp.topMargin = lp.bottomMargin = avataPadding; llInner.addView(ivArrow, lp); pbRefreshing = new ProgressBar(context); resId = ResHelper.getBitmapRes(context, "ssdk_oks_classic_progressbar"); Drawable pbdrawable = context.getResources().getDrawable(resId); pbRefreshing.setIndeterminateDrawable(pbdrawable); llInner.addView(pbRefreshing, lp); pbRefreshing.setVisibility(View.GONE); tvHeader = new TextView(getContext()); tvHeader.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); tvHeader.setPadding(avataPadding, 0, avataPadding, 0); tvHeader.setTextColor(0xff09bb07); lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp.gravity = Gravity.CENTER_VERTICAL; llInner.addView(tvHeader, lp); } public void onPullDown(int percent) { if (percent > 100) { int degree = (percent - 100) * 180 / 20; if (degree > 180) { degree = 180; } if (degree < 0) { degree = 0; } ivArrow.setRotation(degree); } else { ivArrow.setRotation(0); } if (percent < 100) { int resId = ResHelper.getStringRes(getContext(), "ssdk_oks_pull_to_refresh"); if (resId > 0) { tvHeader.setText(resId); } } else { int resId = ResHelper.getStringRes(getContext(), "ssdk_oks_release_to_refresh"); if (resId > 0) { tvHeader.setText(resId); } } } public void onRequest() { ivArrow.setVisibility(View.GONE); pbRefreshing.setVisibility(View.VISIBLE); int resId = ResHelper.getStringRes(getContext(), "ssdk_oks_refreshing"); if (resId > 0) { tvHeader.setText(resId); } } public void reverse() { pbRefreshing.setVisibility(View.GONE); ivArrow.setRotation(180); ivArrow.setVisibility(View.VISIBLE); } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/PicViewerPage.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic; import android.graphics.Bitmap; import android.graphics.drawable.ColorDrawable; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.ImageView.ScaleType; import cn.sharesdk.onekeyshare.OnekeySharePage; import cn.sharesdk.onekeyshare.OnekeyShareThemeImpl; import com.mob.tools.gui.ScaledImageView; /** 图片浏览的视图类 */ public class PicViewerPage extends OnekeySharePage implements OnGlobalLayoutListener { private Bitmap pic; /** 图片浏览的缩放控件 */ private ScaledImageView sivViewer; public PicViewerPage(OnekeyShareThemeImpl impl) { super(impl); } /** 设置图片用于浏览 */ public void setImageBitmap(Bitmap pic) { this.pic = pic; } public void onCreate() { activity.getWindow().setBackgroundDrawable(new ColorDrawable(0x4c000000)); sivViewer = new ScaledImageView(activity); sivViewer.setScaleType(ScaleType.MATRIX); activity.setContentView(sivViewer); if (pic != null) { sivViewer.getViewTreeObserver().addOnGlobalLayoutListener(this); } } public void onGlobalLayout() { sivViewer.getViewTreeObserver().removeGlobalOnLayoutListener(this); sivViewer.post(new Runnable() { public void run() { sivViewer.setBitmap(pic); } }); } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/PlatformPage.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic; import java.util.ArrayList; import java.util.HashMap; import android.graphics.drawable.ColorDrawable; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import android.widget.LinearLayout; import android.widget.TextView; import cn.sharesdk.framework.CustomPlatform; import cn.sharesdk.framework.Platform; import cn.sharesdk.framework.Platform.ShareParams; import cn.sharesdk.framework.ShareSDK; import cn.sharesdk.onekeyshare.CustomerLogo; import cn.sharesdk.onekeyshare.OnekeySharePage; import cn.sharesdk.onekeyshare.OnekeyShareThemeImpl; import com.mob.tools.gui.MobViewPager; import com.mob.tools.utils.ResHelper; /** 九宫格的抽象类 */ public abstract class PlatformPage extends OnekeySharePage { private ClassicTheme impl; /** 点击九格宫,展示编辑界面,要执行的子线程 */ private Runnable beforeFinish; /** 九宫格显示时的动画 */ private Animation animShow; /** 九宫格隐藏时的动画 */ private Animation animHide; private LinearLayout llPanel; private boolean finished; public PlatformPage(OnekeyShareThemeImpl impl) { super(impl); this.impl = ResHelper.forceCast(impl); } public void onCreate() { activity.getWindow().setBackgroundDrawable(new ColorDrawable(0x4c000000)); initAnims(); LinearLayout llPage = new LinearLayout(activity); llPage.setOrientation(LinearLayout.VERTICAL); activity.setContentView(llPage); TextView vTop = new TextView(activity); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); lp.weight = 1; vTop.setOnClickListener(new OnClickListener() { public void onClick(View v) { finish(); } }); llPage.addView(vTop, lp); llPanel = new LinearLayout(activity); llPanel.setOrientation(LinearLayout.VERTICAL); lp = new LinearLayout.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); llPanel.setAnimation(animShow); llPage.addView(llPanel, lp); MobViewPager mvp = new MobViewPager(activity); ArrayList cells = collectCells(); PlatformPageAdapter adapter = newAdapter(cells); lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, adapter.getPanelHeight()); llPanel.addView(mvp, lp); IndicatorView vInd = new IndicatorView(activity); lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, adapter.getBottomHeight()); llPanel.addView(vInd, lp); vInd.setScreenCount(adapter.getCount()); vInd.onScreenChange(0, 0); adapter.setIndicator(vInd); mvp.setAdapter(adapter); } protected abstract PlatformPageAdapter newAdapter(ArrayList cells); protected ArrayList collectCells() { ArrayList cells = new ArrayList(); Platform[] platforms = ShareSDK.getPlatformList(); if (platforms == null) { platforms = new Platform[0]; } HashMap hides = getHiddenPlatforms(); if (hides == null) { hides = new HashMap(); } for (Platform p : platforms) { if (!hides.containsKey(p.getName())) { cells.add(p); } } ArrayList customers = getCustomerLogos(); if (customers != null && customers.size() > 0) { cells.addAll(customers); } return cells; } public final void showEditPage(final Platform platform) { beforeFinish = new Runnable() { public void run() { boolean isSilent = isSilent(); boolean isCustomPlatform = platform instanceof CustomPlatform; boolean isUseClientToShare = isUseClientToShare(platform); if (isSilent || isCustomPlatform || isUseClientToShare) { shareSilently(platform); } else { ShareParams sp = formateShareData(platform); if (sp != null) { // 编辑分享内容的统计 ShareSDK.logDemoEvent(3, null); if (getCustomizeCallback() != null) { getCustomizeCallback().onShare(platform, sp); } impl.showEditPage(activity, platform, sp); } } } }; finish(); } public final void performCustomLogoClick(final View v, final CustomerLogo logo) { beforeFinish = new Runnable() { public void run() { logo.listener.onClick(v); } }; finish(); } private void initAnims() { animShow = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1, Animation.RELATIVE_TO_SELF, 0); animShow.setDuration(300); animHide = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1); animHide.setDuration(300); } public boolean onFinish() { if (finished) { finished = false; return false; } animHide.setAnimationListener(new Animation.AnimationListener() { public void onAnimationStart(Animation animation) { } public void onAnimationRepeat(Animation animation) { } public void onAnimationEnd(Animation animation) { if (beforeFinish == null) { // 取消分享菜单的统计 ShareSDK.logDemoEvent(2, null); } else { beforeFinish.run(); beforeFinish = null; } finished = true; finish(); } }); llPanel.clearAnimation(); llPanel.setAnimation(animHide); llPanel.setVisibility(View.GONE); return true; } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/PlatformPageAdapter.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic; import java.util.ArrayList; import android.content.Context; import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; import android.widget.ImageView.ScaleType; import android.widget.LinearLayout; import android.widget.TextView; import cn.sharesdk.framework.Platform; import cn.sharesdk.onekeyshare.CustomerLogo; import com.mob.tools.gui.ViewPagerAdapter; import com.mob.tools.utils.ResHelper; /** 九宫格的适配器抽象类 */ public abstract class PlatformPageAdapter extends ViewPagerAdapter implements OnClickListener { /** 1秒内多次点击九格宫内的图标无效 */ protected static final int MIN_CLICK_INTERVAL = 1000; public static final int DESIGN_BOTTOM_HEIGHT = 52; /** 九格宫内图标排列的二维数组,一维对应平台,二维对应页数 */ protected Object[][] cells; private PlatformPage page; private IndicatorView vInd; protected int bottomHeight; protected int panelHeight; protected int cellHeight; protected int lineSize; protected int sepLineWidth; protected int paddingTop; protected int logoHeight; private long lastClickTime; public PlatformPageAdapter(PlatformPage page, ArrayList cells) { this.page = page; if (cells != null && !cells.isEmpty()) { calculateSize(page.getContext(), cells); collectCells(cells); } } /** 计算九宫格的格数,行数,格高,行高,图标大小 */ protected abstract void calculateSize(Context context, ArrayList plats); /** 计算九宫格的格数,行数 */ protected abstract void collectCells(ArrayList plats); public int getBottomHeight() { return bottomHeight; } public int getPanelHeight() { return panelHeight; } public int getCount() { return cells == null? 0: cells.length; } public void setIndicator(IndicatorView view) { vInd = view; } public void onScreenChange(int currentScreen, int lastScreen) { if (vInd != null) { vInd.setScreenCount(getCount()); vInd.onScreenChange(currentScreen, lastScreen); } } public View getView(int index, View convertView, ViewGroup parent) { if (convertView == null) { convertView = createPanel(parent.getContext()); } LinearLayout llPanel = ResHelper.forceCast(convertView); LinearLayout[] llCells = ResHelper.forceCast(llPanel.getTag()); refreshPanel(llCells, cells[index]); return convertView; } private View createPanel(Context context) { LinearLayout llPanel = new LinearLayout(context); llPanel.setOrientation(LinearLayout.VERTICAL); llPanel.setBackgroundColor(0xfff2f2f2); int lineCount = panelHeight / cellHeight; LinearLayout[] llCells = new LinearLayout[lineCount * lineSize]; llPanel.setTag(llCells); int cellBack = ResHelper.getBitmapRes(context, "ssdk_oks_classic_platform_cell_back"); LinearLayout.LayoutParams lp; for (int i = 0; i < lineCount; i++) { LinearLayout llLine = new LinearLayout(context); lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, cellHeight); llPanel.addView(llLine, lp); for (int j = 0; j < lineSize; j++) { llCells[i * lineSize + j] = new LinearLayout(context); llCells[i * lineSize + j].setBackgroundResource(cellBack); llCells[i * lineSize + j].setOrientation(LinearLayout.VERTICAL); lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, cellHeight); lp.weight = 1; llLine.addView(llCells[i * lineSize + j], lp); if (j < lineSize - 1) { View vSep = new View(context); lp = new LinearLayout.LayoutParams(sepLineWidth, LayoutParams.MATCH_PARENT); llLine.addView(vSep, lp); } } View vSep = new View(context); lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, sepLineWidth); llPanel.addView(vSep, lp); } for (LinearLayout llCell : llCells) { ImageView ivLogo = new ImageView(context); ivLogo.setScaleType(ScaleType.CENTER_INSIDE); lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, logoHeight); lp.topMargin = paddingTop; llCell.addView(ivLogo, lp); TextView tvName = new TextView(context); tvName.setTextColor(0xff646464); tvName.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); tvName.setGravity(Gravity.CENTER); lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); lp.weight = 1; llCell.addView(tvName, lp); } return llPanel; } private void refreshPanel(LinearLayout[] llCells, Object[] logos) { int cellBack = ResHelper.getBitmapRes(page.getContext(), "ssdk_oks_classic_platform_cell_back"); int disableBack = ResHelper.getBitmapRes(page.getContext(), "ssdk_oks_classic_platfrom_cell_back_nor"); for (int i = 0; i < logos.length; i++) { ImageView ivLogo = ResHelper.forceCast(llCells[i].getChildAt(0)); TextView tvName = ResHelper.forceCast(llCells[i].getChildAt(1)); if (logos[i] == null) { ivLogo.setVisibility(View.INVISIBLE); tvName.setVisibility(View.INVISIBLE); llCells[i].setBackgroundResource(disableBack); llCells[i].setOnClickListener(null); } else { ivLogo.setVisibility(View.VISIBLE); tvName.setVisibility(View.VISIBLE); llCells[i].setBackgroundResource(cellBack); llCells[i].setOnClickListener(this); llCells[i].setTag(logos[i]); if (logos[i] instanceof CustomerLogo) { CustomerLogo logo = ResHelper.forceCast(logos[i]); if (logo.logo != null) { ivLogo.setImageBitmap(logo.logo); } else { ivLogo.setImageBitmap(null); } if (logo.label != null) { tvName.setText(logo.label); } else { tvName.setText(""); } } else { Platform plat = ResHelper.forceCast(logos[i]); String name = plat.getName().toLowerCase(); int resId = ResHelper.getBitmapRes(ivLogo.getContext(),"ssdk_oks_classic_" + name); if (resId > 0) { ivLogo.setImageResource(resId); } else { ivLogo.setImageBitmap(null); } resId = ResHelper.getStringRes(tvName.getContext(), "ssdk_" + name); if (resId > 0) { tvName.setText(resId); } else { tvName.setText(""); } } } } } public void onClick(View v) { long time = System.currentTimeMillis(); if (time - lastClickTime < MIN_CLICK_INTERVAL) { return; } lastClickTime = time; if (v.getTag() instanceof CustomerLogo) { CustomerLogo logo = ResHelper.forceCast(v.getTag()); page.performCustomLogoClick(v, logo); } else { Platform plat = ResHelper.forceCast(v.getTag()); page.showEditPage(plat); } } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/RotateImageView.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic; import android.content.Context; import android.graphics.Canvas; import android.widget.ImageView; /** 在At好友页面中,下拉刷新列表头部的旋转箭头 */ public class RotateImageView extends ImageView { private float rotation; public RotateImageView(Context context) { super(context); } public void setRotation(float rotation) { this.rotation = rotation; invalidate(); } protected void onDraw(Canvas canvas) { canvas.rotate(rotation, getWidth() / 2, getHeight() / 2); super.onDraw(canvas); } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/XView.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.view.View; /** 编辑页面中删除图片“X”按钮 */ public class XView extends View { private float ratio; public XView(Context context) { super(context); } public void setRatio(float ratio) { this.ratio = ratio; } protected void onDraw(Canvas canvas) { int width = getWidth() / 2; int height = getHeight() / 2; Paint paint = new Paint(); paint.setAntiAlias(true); paint.setColor(0xffa0a0a0); canvas.drawRect(width, 0, getWidth(), height, paint); paint = new Paint(); paint.setAntiAlias(true); paint.setStrokeWidth(3f * ratio); paint.setColor(0xffffffff); float left = 8f * ratio; canvas.drawLine(width + left, left, getWidth() - left, width - left, paint); canvas.drawLine(width + left, width - left, getWidth() - left, left, paint); } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/land/EditPageLand.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic.land; import java.io.File; import android.graphics.Bitmap; import android.text.TextUtils; import android.text.TextWatcher; import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; import cn.sharesdk.onekeyshare.OnekeyShareThemeImpl; import cn.sharesdk.onekeyshare.themes.classic.EditPage; import cn.sharesdk.onekeyshare.themes.classic.XView; import com.mob.tools.gui.AsyncImageView; import com.mob.tools.utils.BitmapHelper; import com.mob.tools.utils.ResHelper; /** 横屏的编辑页 */ public class EditPageLand extends EditPage implements OnClickListener, TextWatcher, Runnable { private static final int DESIGN_SCREEN_WIDTH= 720; private static final int DESIGN_BOTTOM_HEIGHT = 75; private static final int DESIGN_LEFT_PADDING = 40; private static final int DESIGN_TITLE_HEIGHT_L = 70; private static final int DESIGN_THUMB_HEIGHT_L = 280; private static final int DESIGN_REMOVE_THUMB_HEIGHT_L = 60; public EditPageLand(OnekeyShareThemeImpl impl) { super(impl); } public void onCreate() { super.onCreate(); int screenHeight = ResHelper.getScreenHeight(activity); float ratio = ((float) screenHeight) / DESIGN_SCREEN_WIDTH; maxBodyHeight = 0; llPage = new LinearLayout(activity); llPage.setOrientation(LinearLayout.VERTICAL); activity.setContentView(llPage); rlTitle = new RelativeLayout(activity); rlTitle.setBackgroundColor(0xffe6e9ec); int titleHeight = (int) (DESIGN_TITLE_HEIGHT_L * ratio); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, titleHeight); llPage.addView(rlTitle, lp); initTitle(rlTitle, ratio); RelativeLayout rlBody = new RelativeLayout(activity); rlBody.setBackgroundColor(0xffffffff); lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); llPage.addView(rlBody, lp); initBody(rlBody, ratio); LinearLayout llShadow = new LinearLayout(activity); llShadow.setOrientation(LinearLayout.VERTICAL); rlBody.addView(llShadow, new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); initShadow(llShadow, ratio); llBottom = new LinearLayout(activity); llBottom.setOrientation(LinearLayout.VERTICAL); lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); llPage.addView(llBottom, lp); initBottom(llBottom, ratio); } private void initTitle(RelativeLayout rlTitle, float ratio) { tvCancel = new TextView(activity); tvCancel.setTextColor(0xff3b3b3b); tvCancel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); tvCancel.setGravity(Gravity.CENTER); int resId = ResHelper.getStringRes(activity, "ssdk_oks_cancel"); if (resId > 0) { tvCancel.setText(resId); } int padding = (int) (DESIGN_LEFT_PADDING * ratio); tvCancel.setPadding(padding, 0, padding, 0); RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); rlTitle.addView(tvCancel, lp); tvCancel.setOnClickListener(this); TextView tvTitle = new TextView(activity); tvTitle.setTextColor(0xff3b3b3b); tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22); tvTitle.setGravity(Gravity.CENTER); resId = ResHelper.getStringRes(activity, "ssdk_oks_multi_share"); if (resId > 0) { tvTitle.setText(resId); } lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); lp.addRule(RelativeLayout.CENTER_IN_PARENT); rlTitle.addView(tvTitle, lp); tvShare = new TextView(activity); tvShare.setTextColor(0xffff6d11); tvShare.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); tvShare.setGravity(Gravity.CENTER); resId = ResHelper.getStringRes(activity, "ssdk_oks_share"); if (resId > 0) { tvShare.setText(resId); } tvShare.setPadding(padding, 0, padding, 0); lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); rlTitle.addView(tvShare, lp); tvShare.setOnClickListener(this); } private void initBody(RelativeLayout rlBody, float ratio) { svContent = new ScrollView(activity); rlBody.addView(svContent, new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); LinearLayout llContent = new LinearLayout(activity); llContent.setOrientation(LinearLayout.HORIZONTAL); svContent.addView(llContent, new ScrollView.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); etContent = new EditText(activity); int padding = (int) (DESIGN_LEFT_PADDING * ratio); etContent.setPadding(padding, padding, padding, padding); etContent.setBackgroundDrawable(null); etContent.setTextColor(0xff3b3b3b); etContent.setTextSize(TypedValue.COMPLEX_UNIT_SP, 21); etContent.setText(sp.getText()); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT); lp.weight = 1; llContent.addView(etContent, lp); etContent.addTextChangedListener(this); rlThumb = new RelativeLayout(activity); rlThumb.setBackgroundColor(0xff313131); int thumbWidth = (int) (DESIGN_THUMB_HEIGHT_L * ratio); int xWidth = (int) (DESIGN_REMOVE_THUMB_HEIGHT_L * ratio); lp = new LinearLayout.LayoutParams(thumbWidth, thumbWidth); lp.rightMargin = lp.bottomMargin = lp.topMargin = padding; llContent.addView(rlThumb, lp); aivThumb = new AsyncImageView(activity) { public void onImageGot(String url, Bitmap bm) { thumb = bm; super.onImageGot(url, bm); } }; aivThumb.setScaleToCropCenter(true); RelativeLayout.LayoutParams rllp = new RelativeLayout.LayoutParams(thumbWidth, thumbWidth); rlThumb.addView(aivThumb, rllp); aivThumb.setOnClickListener(this); initThumb(aivThumb); xvRemove = new XView(activity); xvRemove.setRatio(ratio); rllp = new RelativeLayout.LayoutParams(xWidth, xWidth); rllp.addRule(RelativeLayout.ALIGN_PARENT_TOP); rllp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); rlThumb.addView(xvRemove, rllp); xvRemove.setOnClickListener(this); } private void initBottom(LinearLayout llBottom, float ratio) { LinearLayout llAt = new LinearLayout(activity); llAt.setPadding(0, 0, 0, 5); llAt.setBackgroundColor(0xffffffff); int bottomHeight = (int) (DESIGN_BOTTOM_HEIGHT * ratio); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, bottomHeight); llBottom.addView(llAt, lp); tvAt = new TextView(activity); tvAt.setTextColor(0xff3b3b3b); tvAt.setTextSize(TypedValue.COMPLEX_UNIT_SP, 21); tvAt.setGravity(Gravity.BOTTOM); tvAt.setText("@"); int padding = (int) (DESIGN_LEFT_PADDING * ratio); tvAt.setPadding(padding, 0, padding, 0); lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); llAt.addView(tvAt, lp); tvAt.setOnClickListener(this); if (isShowAtUserLayout(platform.getName())) { tvAt.setVisibility(View.VISIBLE); } else { tvAt.setVisibility(View.INVISIBLE); } tvTextCouter = new TextView(activity); tvTextCouter.setTextColor(0xff3b3b3b); tvTextCouter.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); tvTextCouter.setGravity(Gravity.BOTTOM | Gravity.RIGHT); onTextChanged(etContent.getText(), 0, 0, 0); tvTextCouter.setPadding(padding, 0, padding, 0); lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); lp.weight = 1; llAt.addView(tvTextCouter, lp); View v = new View(activity); v.setBackgroundColor(0xffcccccc); int px_1 = ratio > 1 ? ((int) ratio) : 1; lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, px_1); llBottom.addView(v, lp); } private void initShadow(LinearLayout llShadow, float ratio) { int px_1 = ratio > 1 ? ((int) ratio) : 1; LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, px_1); View v = new View(activity); v.setBackgroundColor(0x29000000); llShadow.addView(v, lp); v = new View(activity); v.setBackgroundColor(0x14000000); llShadow.addView(v, lp); v = new View(activity); v.setBackgroundColor(0x07000000); llShadow.addView(v, lp); } private void initThumb(AsyncImageView aivThumb) { String imageUrl = sp.getImageUrl(); String imagePath = sp.getImagePath(); String[] imageArray = sp.getImageArray(); Bitmap pic = null; rlThumb.setVisibility(View.VISIBLE); if(!TextUtils.isEmpty(imagePath) && new File(imagePath).exists()) { try { pic = BitmapHelper.getBitmap(imagePath); } catch (Throwable e) { e.printStackTrace(); } } if (pic != null) { thumb = pic; aivThumb.setBitmap(pic); } else if (imageArray != null && imageArray.length > 0) { if (!TextUtils.isEmpty(imageArray[0]) && new File(imageArray[0]).exists()) { try { pic = BitmapHelper.getBitmap(imagePath); } catch (Throwable e) { e.printStackTrace(); } } } if (pic != null) { thumb = pic; aivThumb.setBitmap(pic); } else if (pic == null && !TextUtils.isEmpty(imageUrl)) { aivThumb.execute(imageUrl, 0); } else { rlThumb.setVisibility(View.GONE); } } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/land/FriendListPageLand.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic.land; import cn.sharesdk.onekeyshare.OnekeyShareThemeImpl; import cn.sharesdk.onekeyshare.themes.classic.FriendListPage; import com.mob.tools.utils.ResHelper; /** 横屏的好友列表 */ public class FriendListPageLand extends FriendListPage { private static final int DESIGN_SCREEN_WIDTH = 1280; private static final int DESIGN_TITLE_HEIGHT = 70; public FriendListPageLand(OnekeyShareThemeImpl impl) { super(impl); } protected float getRatio() { float screenWidth = ResHelper.getScreenWidth(activity); return screenWidth / DESIGN_SCREEN_WIDTH; } protected int getDesignTitleHeight() { return DESIGN_TITLE_HEIGHT; } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/land/PlatformPageAdapterLand.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic.land; import java.util.ArrayList; import android.content.Context; import cn.sharesdk.onekeyshare.themes.classic.PlatformPage; import cn.sharesdk.onekeyshare.themes.classic.PlatformPageAdapter; import com.mob.tools.utils.ResHelper; /** 横屏的九宫格页面适配器 */ public class PlatformPageAdapterLand extends PlatformPageAdapter { private static final int DESIGN_SCREEN_WIDTH_L = 1280; private static final int DESIGN_CELL_WIDTH_L = 160; private static final int DESIGN_SEP_LINE_WIDTH = 1; private static final int DESIGN_LOGO_HEIGHT = 76; private static final int DESIGN_PADDING_TOP = 20; public PlatformPageAdapterLand(PlatformPage page, ArrayList cells) { super(page, cells); } protected void calculateSize(Context context, ArrayList plats) { int screenWidth = ResHelper.getScreenWidth(context); float ratio = ((float) screenWidth) / DESIGN_SCREEN_WIDTH_L; int cellWidth = (int) (DESIGN_CELL_WIDTH_L * ratio); lineSize = screenWidth / cellWidth; sepLineWidth = (int) (DESIGN_SEP_LINE_WIDTH * ratio); sepLineWidth = sepLineWidth < 1 ? 1 : sepLineWidth; logoHeight = (int) (DESIGN_LOGO_HEIGHT * ratio); paddingTop = (int) (DESIGN_PADDING_TOP * ratio); bottomHeight = (int) (DESIGN_BOTTOM_HEIGHT * ratio); cellHeight = (screenWidth - sepLineWidth * 3) / (lineSize - 1); panelHeight = cellHeight + sepLineWidth; } protected void collectCells(ArrayList plats) { int count = plats.size(); if (count < lineSize) { int lineCount = (count / lineSize); if (count % lineSize != 0) { lineCount++; } cells = new Object[1][lineCount * lineSize]; } else { int pageCount = (count / lineSize); if (count % lineSize != 0) { pageCount++; } cells = new Object[pageCount][lineSize]; } for (int i = 0; i < count; i++) { int p = i / lineSize; cells[p][i - lineSize * p] = plats.get(i); } } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/land/PlatformPageLand.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic.land; import java.util.ArrayList; import cn.sharesdk.onekeyshare.OnekeyShareThemeImpl; import cn.sharesdk.onekeyshare.themes.classic.PlatformPage; import cn.sharesdk.onekeyshare.themes.classic.PlatformPageAdapter; /** 横屏的九宫格页面 */ public class PlatformPageLand extends PlatformPage { public PlatformPageLand(OnekeyShareThemeImpl impl) { super(impl); } public void onCreate() { requestLandscapeOrientation(); super.onCreate(); } protected PlatformPageAdapter newAdapter(ArrayList cells) { return new PlatformPageAdapterLand(this, cells); } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/port/EditPagePort.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic.port; import java.io.File; import android.graphics.Bitmap; import android.text.TextUtils; import android.util.TypedValue; import android.view.Gravity; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; import cn.sharesdk.onekeyshare.OnekeyShareThemeImpl; import cn.sharesdk.onekeyshare.themes.classic.EditPage; import cn.sharesdk.onekeyshare.themes.classic.XView; import com.mob.tools.gui.AsyncImageView; import com.mob.tools.utils.BitmapHelper; import com.mob.tools.utils.ResHelper; /** 竖屏的编辑页 */ public class EditPagePort extends EditPage { private static final int DESIGN_SCREEN_HEIGHT= 1280; private static final int DESIGN_TITLE_HEIGHT = 96; private static final int DESIGN_BOTTOM_HEIGHT = 75; private static final int DESIGN_LEFT_PADDING = 40; private static final int DESIGN_THUMB_HEIGHT = 300; private static final int DESIGN_REMOVE_THUMB_HEIGHT = 70; public EditPagePort(OnekeyShareThemeImpl impl) { super(impl); } public void onCreate() { super.onCreate(); int screenHeight = ResHelper.getScreenHeight(activity); float ratio = ((float) screenHeight) / DESIGN_SCREEN_HEIGHT; maxBodyHeight = 0; llPage = new LinearLayout(activity); llPage.setOrientation(LinearLayout.VERTICAL); activity.setContentView(llPage); rlTitle = new RelativeLayout(activity); rlTitle.setBackgroundColor(0xffe6e9ec); int titleHeight = (int) (DESIGN_TITLE_HEIGHT * ratio); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, titleHeight); llPage.addView(rlTitle, lp); initTitle(rlTitle, ratio); RelativeLayout rlBody = new RelativeLayout(activity); rlBody.setBackgroundColor(0xffffffff); lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); llPage.addView(rlBody, lp); initBody(rlBody, ratio); LinearLayout llShadow = new LinearLayout(activity); llShadow.setOrientation(LinearLayout.VERTICAL); rlBody.addView(llShadow, new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); initShadow(llShadow, ratio); llBottom = new LinearLayout(activity); llBottom.setOrientation(LinearLayout.VERTICAL); lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); llPage.addView(llBottom, lp); initBottom(llBottom, ratio); } private void initTitle(RelativeLayout rlTitle, float ratio) { tvCancel = new TextView(activity); tvCancel.setTextColor(0xff3b3b3b); tvCancel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); tvCancel.setGravity(Gravity.CENTER); int resId = ResHelper.getStringRes(activity, "ssdk_oks_cancel"); if (resId > 0) { tvCancel.setText(resId); } int padding = (int) (DESIGN_LEFT_PADDING * ratio); tvCancel.setPadding(padding, 0, padding, 0); RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); rlTitle.addView(tvCancel, lp); tvCancel.setOnClickListener(this); TextView tvTitle = new TextView(activity); tvTitle.setTextColor(0xff3b3b3b); tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22); tvTitle.setGravity(Gravity.CENTER); resId = ResHelper.getStringRes(activity, "ssdk_oks_multi_share"); if (resId > 0) { tvTitle.setText(resId); } lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); lp.addRule(RelativeLayout.CENTER_IN_PARENT); rlTitle.addView(tvTitle, lp); tvShare = new TextView(activity); tvShare.setTextColor(0xffff6d11); tvShare.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); tvShare.setGravity(Gravity.CENTER); resId = ResHelper.getStringRes(activity, "ssdk_oks_share"); if (resId > 0) { tvShare.setText(resId); } tvShare.setPadding(padding, 0, padding, 0); lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); rlTitle.addView(tvShare, lp); tvShare.setOnClickListener(this); } private void initBody(RelativeLayout rlBody, float ratio) { svContent = new ScrollView(activity); rlBody.addView(svContent, new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); LinearLayout llContent = new LinearLayout(activity); llContent.setOrientation(LinearLayout.VERTICAL); svContent.addView(llContent, new ScrollView.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); etContent = new EditText(activity); int padding = (int) (DESIGN_LEFT_PADDING * ratio); etContent.setPadding(padding, padding, padding, padding); etContent.setBackgroundDrawable(null); etContent.setTextColor(0xff3b3b3b); etContent.setTextSize(TypedValue.COMPLEX_UNIT_SP, 21); etContent.setText(sp.getText()); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT); llContent.addView(etContent, lp); etContent.addTextChangedListener(this); rlThumb = new RelativeLayout(activity); rlThumb.setBackgroundColor(0xff313131); int thumbWidth = (int) (DESIGN_THUMB_HEIGHT * ratio); int xWidth = (int) (DESIGN_REMOVE_THUMB_HEIGHT * ratio); lp = new LinearLayout.LayoutParams(thumbWidth, thumbWidth); lp.leftMargin = lp.rightMargin = lp.bottomMargin = lp.topMargin = padding; llContent.addView(rlThumb, lp); aivThumb = new AsyncImageView(activity) { public void onImageGot(String url, Bitmap bm) { thumb = bm; super.onImageGot(url, bm); } }; aivThumb.setScaleToCropCenter(true); RelativeLayout.LayoutParams rllp = new RelativeLayout.LayoutParams(thumbWidth, thumbWidth); rlThumb.addView(aivThumb, rllp); aivThumb.setOnClickListener(this); initThumb(aivThumb); xvRemove = new XView(activity); xvRemove.setRatio(ratio); rllp = new RelativeLayout.LayoutParams(xWidth, xWidth); rllp.addRule(RelativeLayout.ALIGN_PARENT_TOP); rllp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); rlThumb.addView(xvRemove, rllp); xvRemove.setOnClickListener(this); } private void initBottom(LinearLayout llBottom, float ratio) { LinearLayout llAt = new LinearLayout(activity); llAt.setPadding(0, 0, 0, 5); llAt.setBackgroundColor(0xffffffff); int bottomHeight = (int) (DESIGN_BOTTOM_HEIGHT * ratio); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, bottomHeight); llBottom.addView(llAt, lp); tvAt = new TextView(activity); tvAt.setTextColor(0xff3b3b3b); tvAt.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22); tvAt.setGravity(Gravity.BOTTOM); tvAt.setText("@"); int padding = (int) (DESIGN_LEFT_PADDING * ratio); tvAt.setPadding(padding, 0, padding, 0); lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); llAt.addView(tvAt, lp); tvAt.setOnClickListener(this); if (isShowAtUserLayout(platform.getName())) { tvAt.setVisibility(View.VISIBLE); } else { tvAt.setVisibility(View.INVISIBLE); } tvTextCouter = new TextView(activity); tvTextCouter.setTextColor(0xff3b3b3b); tvTextCouter.setTextSize(TypedValue.COMPLEX_UNIT_SP, 21); tvTextCouter.setGravity(Gravity.BOTTOM | Gravity.RIGHT); onTextChanged(etContent.getText(), 0, 0, 0); tvTextCouter.setPadding(padding, 0, padding, 0); lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); lp.weight = 1; llAt.addView(tvTextCouter, lp); View v = new View(activity); v.setBackgroundColor(0xffcccccc); int px_1 = ratio > 1 ? ((int) ratio) : 1; lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, px_1); llBottom.addView(v, lp); } private void initShadow(LinearLayout llShadow, float ratio) { int px_1 = ratio > 1 ? ((int) ratio) : 1; LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, px_1); View v = new View(activity); v.setBackgroundColor(0x29000000); llShadow.addView(v, lp); v = new View(activity); v.setBackgroundColor(0x14000000); llShadow.addView(v, lp); v = new View(activity); v.setBackgroundColor(0x07000000); llShadow.addView(v, lp); } private void initThumb(AsyncImageView aivThumb) { String imageUrl = sp.getImageUrl(); String imagePath = sp.getImagePath(); String[] imageArray = sp.getImageArray(); Bitmap pic = null; rlThumb.setVisibility(View.VISIBLE); if(!TextUtils.isEmpty(imagePath) && new File(imagePath).exists()) { try { pic = BitmapHelper.getBitmap(imagePath); } catch (Throwable e) { e.printStackTrace(); } } if (pic != null) { thumb = pic; aivThumb.setBitmap(pic); } else if (imageArray != null && imageArray.length > 0) { if (!TextUtils.isEmpty(imageArray[0]) && new File(imageArray[0]).exists()) { try { pic = BitmapHelper.getBitmap(imagePath); } catch (Throwable e) { e.printStackTrace(); } } } if (pic != null) { thumb = pic; aivThumb.setBitmap(pic); } else if (pic == null && !TextUtils.isEmpty(imageUrl)) { aivThumb.execute(imageUrl, 0); } else { rlThumb.setVisibility(View.GONE); } } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/port/FriendListPagePort.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic.port; import cn.sharesdk.onekeyshare.OnekeyShareThemeImpl; import cn.sharesdk.onekeyshare.themes.classic.FriendListPage; import com.mob.tools.utils.ResHelper; /** 竖屏的好友列表 */ public class FriendListPagePort extends FriendListPage { private static final int DESIGN_SCREEN_WIDTH = 720; private static final int DESIGN_TITLE_HEIGHT = 96; public FriendListPagePort(OnekeyShareThemeImpl impl) { super(impl); } protected float getRatio() { float screenWidth = ResHelper.getScreenWidth(activity); return screenWidth / DESIGN_SCREEN_WIDTH; } protected int getDesignTitleHeight() { return DESIGN_TITLE_HEIGHT; } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/port/PlatformPageAdapterPort.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic.port; import java.util.ArrayList; import android.content.Context; import cn.sharesdk.onekeyshare.themes.classic.PlatformPage; import cn.sharesdk.onekeyshare.themes.classic.PlatformPageAdapter; import com.mob.tools.utils.ResHelper; /** 竖屏的九宫格页面适配器 */ public class PlatformPageAdapterPort extends PlatformPageAdapter { private static final int DESIGN_SCREEN_WIDTH_P = 720; private static final int DESIGN_SEP_LINE_WIDTH = 1; private static final int DESIGN_LOGO_HEIGHT = 76; private static final int DESIGN_PADDING_TOP = 20; private static final int PAGE_SIZE_P = 12; private static final int LINE_SIZE_P = 4; public PlatformPageAdapterPort(PlatformPage page, ArrayList cells) { super(page, cells); } protected void calculateSize(Context context, ArrayList plats) { int screenWidth = ResHelper.getScreenWidth(context); lineSize = LINE_SIZE_P; float ratio = ((float) screenWidth) / DESIGN_SCREEN_WIDTH_P; sepLineWidth = (int) (DESIGN_SEP_LINE_WIDTH * ratio); sepLineWidth = sepLineWidth < 1 ? 1 : sepLineWidth; logoHeight = (int) (DESIGN_LOGO_HEIGHT * ratio); paddingTop = (int) (DESIGN_PADDING_TOP * ratio); bottomHeight = (int) (DESIGN_BOTTOM_HEIGHT * ratio); cellHeight = (screenWidth - sepLineWidth * 3) / 4; if (plats.size() <= lineSize) { panelHeight = cellHeight + sepLineWidth; } else if (plats.size() <= PAGE_SIZE_P - lineSize) { panelHeight = (cellHeight + sepLineWidth) * 2; } else { panelHeight = (cellHeight + sepLineWidth) * 3; } } protected void collectCells(ArrayList plats) { int count = plats.size(); if (count < PAGE_SIZE_P) { int lineCount = (count / lineSize); if (count % lineSize != 0) { lineCount++; } cells = new Object[1][lineCount * lineSize]; } else { int pageCount = (count / PAGE_SIZE_P); if (count % PAGE_SIZE_P != 0) { pageCount++; } cells = new Object[pageCount][PAGE_SIZE_P]; } for (int i = 0; i < count; i++) { int p = i / PAGE_SIZE_P; cells[p][i - PAGE_SIZE_P * p] = plats.get(i); } } } ================================================ FILE: app/src/main/java/cn/sharesdk/onekeyshare/themes/classic/port/PlatformPagePort.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package cn.sharesdk.onekeyshare.themes.classic.port; import java.util.ArrayList; import cn.sharesdk.onekeyshare.OnekeyShareThemeImpl; import cn.sharesdk.onekeyshare.themes.classic.PlatformPage; import cn.sharesdk.onekeyshare.themes.classic.PlatformPageAdapter; /** 竖屏的九宫格页面 */ public class PlatformPagePort extends PlatformPage { public PlatformPagePort(OnekeyShareThemeImpl impl) { super(impl); } public void onCreate() { requestPortraitOrientation(); super.onCreate(); } protected PlatformPageAdapter newAdapter(ArrayList cells) { return new PlatformPageAdapterPort(this, cells); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/api/CacheApi.java ================================================ package com.ittianyu.pocenter.common.api; import com.ittianyu.pocenter.common.bean.ProjectBean; import java.util.List; import java.util.concurrent.TimeUnit; import io.reactivex.Observable; import io.rx_cache2.DynamicKey; import io.rx_cache2.EvictDynamicKey; import io.rx_cache2.LifeCache; /** * Created by yu on 2017/1/17. */ public interface CacheApi { @LifeCache(duration = 15, timeUnit = TimeUnit.MINUTES) Observable> getList(Observable> repo, DynamicKey key, EvictDynamicKey isUpdate); } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/api/RemoteApi.java ================================================ package com.ittianyu.pocenter.common.api; import com.ittianyu.pocenter.common.bean.ProjectBean; import java.util.List; import io.reactivex.Observable; import retrofit2.http.GET; import retrofit2.http.Query; /** * Created by yu on 2017/1/17. */ public interface RemoteApi { interface Type { int OTHER = 0; int WEB = 1; int WE_CHAT = 2; int HTML5 = 3; int APP = 4; int INTELLIGENT_HARDWARE = 5; int DESKTOP_APP = 6; int BIG_DATA = 7; int SYSTEM = 8; int SDK_API = 9; int ART = 10; } interface Status { int RECRUITING = 0; int RECRUITED = 1; } /** * select list according to types status and keywords * * @param start start index * @param count select count * @param types support multiple types * @param status * @param keywords title or description keywords * @return */ @GET("list") Observable> getList(@Query("start") int start, @Query("count") int count, @Query("type") int[] types, @Query("status") int status, @Query("keyword") String[] keywords); } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/api/Repertories.java ================================================ package com.ittianyu.pocenter.common.api; import android.content.Context; import android.support.annotation.NonNull; import android.text.TextUtils; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.common.base.BaseApplication; import com.ittianyu.pocenter.common.bean.ProjectBean; import com.ittianyu.pocenter.common.utils.ConfigUtils; import com.ittianyu.pocenter.common.utils.RxUtils; import com.ittianyu.pocenter.common.utils.UnsafeOkHttpUtils; import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import io.reactivex.Observable; import io.rx_cache2.DynamicKey; import io.rx_cache2.EvictDynamicKey; import io.rx_cache2.internal.RxCache; import io.victoralbertos.jolyglot.GsonSpeaker; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; /** * Created by yu on 2017/1/17. */ public class Repertories { public static final String HOST = "po.ittianyu.com"; public static final String URL_BASE = "https://" + HOST + "/"; private RemoteApi remoteApi; private CacheApi cacheApi; private List types = new ArrayList<>(); public Repertories(File cacheDir) { // create apis cacheApi = new RxCache.Builder() .useExpiredDataIfLoaderNotAvailable(true) .persistence(cacheDir, new GsonSpeaker()) .using(CacheApi.class); remoteApi = new Retrofit.Builder() .baseUrl(URL_BASE) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .client(UnsafeOkHttpUtils.getClient()) .build() .create(RemoteApi.class); // add types Context context = BaseApplication.getContext(); types.add(context.getString(R.string.type_other)); types.add(context.getString(R.string.type_web)); types.add(context.getString(R.string.type_we_chat)); types.add(context.getString(R.string.type_html5)); types.add(context.getString(R.string.type_app)); types.add(context.getString(R.string.type_intelligent_hardware)); types.add(context.getString(R.string.type_desktop_app)); types.add(context.getString(R.string.type_big_data)); types.add(context.getString(R.string.type_system)); types.add(context.getString(R.string.type_sdk_api)); types.add(context.getString(R.string.type_art)); } public Observable> getList(int start, int count, int[] types, int status, String[] keywords, boolean update) { String key = generateKey(start, count, types, status, keywords); return cacheApi.getList(remoteApi.getList(start, count, types, status, keywords), new DynamicKey(key), new EvictDynamicKey(update)) .compose(RxUtils.>netScheduler());// net on io thread, subscribe on main thread // return remoteApi.getList(start, count, types, status, keywords) // .compose(RxUtils.>netScheduler());// net on io thread, subscribe on main thread } /** * according params to generate key * @param start * @param count * @param types * @param status * @param keywords * @return */ @NonNull private String generateKey(int start, int count, int[] types, int status, String[] keywords) { StringBuilder keyBuilder = new StringBuilder("start=" + start + "&count=" + count); if (null != types && types.length > 0) { Arrays.sort(types); for (int type : types) { keyBuilder.append("&type=" + type); } } keyBuilder.append("&status=" + status); if (null != keywords && keywords.length > 0) { Arrays.sort(keywords); for (String keyword : keywords) { keyBuilder.append("&keyword=" + keyword); } } return keyBuilder.toString(); } public List getAllTypes() { return types; } public boolean isSettingTypes() { // load config String type = ConfigUtils.getString(BaseApplication.getContext(), ConfigUtils.KEY_TYPE, ""); if (TextUtils.isEmpty(type)) return false; return true; } public int[] getTypes() { String type = ConfigUtils.getString(BaseApplication.getContext(), ConfigUtils.KEY_TYPE, ""); if (TextUtils.isEmpty(type)) return null; String[] typesString = type.split(","); if (0 == typesString.length) return null; int[] types = new int[typesString.length]; for (int i = 0; i < typesString.length; i++) { types[i] = Integer.parseInt(typesString[i]); } return types; } public void setTypes(Set set) { // create types string StringBuilder typeBuilder = new StringBuilder(); for (int type : set) { typeBuilder.append(type); typeBuilder.append(','); } typeBuilder.deleteCharAt(typeBuilder.length() - 1);// delete the last ',' // save to file ConfigUtils.putString(BaseApplication.getContext(), ConfigUtils.KEY_TYPE, typeBuilder.toString()); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/base/BaseActivity.java ================================================ package com.ittianyu.pocenter.common.base; import android.view.View; import android.widget.TextView; import com.ittianyu.mvp.lcee.Lcee; import com.ittianyu.mvp.lcee.MvpLceeActivity; import com.ittianyu.pocenter.R; import com.orhanobut.logger.Logger; /** * Created by yu on 2016/11/25. */ @Lcee(loadingViewId = R.id.v_loading, contentViewId = R.id.v_content, errorViewId = R.id.v_error, emptyViewId = R.id.v_empty) public abstract class BaseActivity, P extends BaseContract.Presenter> extends MvpLceeActivity implements BaseContract.View { // protected View view;// cache view // protected boolean firstLoad = true; @Override protected void onStart() { super.onStart(); initView(); loadData(false); } // /** // * create view // * It will be only create once in a life // * No need set content view when onCreate // */ // protected abstract View createView(); /** * init view */ protected abstract void initView(); @Override protected String getErrorMessage(Throwable e, boolean pullToRefresh) { Logger.e(e, ""); return pullToRefresh ? getString(R.string.failed_to_refresh) : getString(R.string.failed_to_load_click_to_reload); } @Override protected void onSetErrorViewText(View errorView, String errorMsg) { TextView tv = (TextView) errorView.findViewById(R.id.tv); tv.setText(errorMsg); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/base/BaseApplication.java ================================================ package com.ittianyu.pocenter.common.base; import android.app.Application; import android.content.Context; import android.content.pm.ApplicationInfo; import android.support.multidex.MultiDex; import com.ittianyu.pocenter.BuildConfig; import com.ittianyu.pocenter.common.api.Repertories; import com.ittianyu.pocenter.common.tinker.FetchPatchHandler; import com.orhanobut.logger.LogLevel; import com.orhanobut.logger.Logger; import com.squareup.leakcanary.LeakCanary; import com.tencent.tinker.loader.app.ApplicationLike; import com.tinkerpatch.sdk.TinkerPatch; import com.tinkerpatch.sdk.loader.TinkerPatchApplicationLike; /** * Created by yu on 2016/11/24. */ public class BaseApplication extends Application { private static Context context; private static Repertories repertories; // tinker patch config private ApplicationLike tinkerApplicationLike; @Override public void onCreate() { super.onCreate(); // tinker patch config tinkerPatchConfig(); context = getApplicationContext(); initLogger(); initLeakCanary(); repertories = new Repertories(context.getCacheDir()); } private void tinkerPatchConfig() { // 我们可以从这里获得Tinker加载过程的信息 if (BuildConfig.TINKER_ENABLE) { tinkerApplicationLike = TinkerPatchApplicationLike.getTinkerPatchApplicationLike(); // 初始化TinkerPatch SDK TinkerPatch.init(tinkerApplicationLike) .reflectPatchLibrary() .setPatchRollbackOnScreenOff(true) .setPatchRestartOnSrceenOff(true); // 每隔3个小时去访问后台时候有更新,通过handler实现轮训的效果 new FetchPatchHandler().fetchPatchWithInterval(3); } } /** * use LeakCanary to check mey leak */ private void initLeakCanary() { if (LeakCanary.isInAnalyzerProcess(this)) { // This process is dedicated to LeakCanary for heap analysis. // You should not init your app in this process. return; } LeakCanary.install(this); } /** * init logger */ private void initLogger() { if ((0 != (getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE))) Logger.init(); // for debug, print all log else Logger.init().logLevel(LogLevel.NONE); // for release, remove all log // Logger.init(); // for release, remove all log } public static Context getContext() { return context; } public static Repertories getRepertories() { return repertories; } /** * tinker * @param base */ @Override public void attachBaseContext(Context base) { super.attachBaseContext(base); //you must install multiDex whatever tinker is installed! MultiDex.install(base); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/base/BaseContract.java ================================================ package com.ittianyu.pocenter.common.base; import com.hannesdorfmann.mosby.mvp.MvpPresenter; import com.ittianyu.mvp.lcee.MvpLceeView; /** * Created by yu on 2016/11/29. */ public interface BaseContract { interface View extends MvpLceeView { T getApp(); } interface Presenter extends MvpPresenter { BaseApplication getApp(); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/base/BaseFragment.java ================================================ package com.ittianyu.pocenter.common.base; import android.os.Bundle; import android.support.annotation.Nullable; import android.view.View; import android.widget.TextView; import com.ittianyu.mvp.lcee.Lcee; import com.ittianyu.mvp.lcee.MvpLceeFragment; import com.ittianyu.pocenter.R; import com.orhanobut.logger.Logger; import com.victor.loading.rotate.RotateLoading; /** * Created by yu on 2016/11/25. */ @Lcee(loadingViewId = R.id.v_loading, contentViewId = R.id.v_content, errorViewId = R.id.v_error, emptyViewId = R.id.v_empty) public abstract class BaseFragment, P extends BaseContract.Presenter> extends MvpLceeFragment implements BaseContract.View { protected boolean firstLoad = true; protected boolean prepared = false; protected boolean visible = false; @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); visible = isVisibleToUser; lazyLoad(); } /** * only load data at first visible */ private void lazyLoad() { if (visible && firstLoad && prepared) { firstLoad = false; loadData(false); } } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); initView(view); showLoading(false); prepared = true; lazyLoad(); } /** * init view */ protected abstract void initView(View view); @Override protected String getErrorMessage(Throwable e, boolean pullToRefresh) { Logger.e(e, e.getMessage()); return pullToRefresh ? getString(R.string.failed_to_refresh) : getString(R.string.failed_to_load_click_to_reload); } @Override protected void onSetErrorViewText(View errorView, String errorMsg) { TextView tv = (TextView) errorView.findViewById(R.id.tv); tv.setText(errorMsg); } @Override public T getApp() { return (T) getActivity().getApplication(); } @Override public void showLoading(boolean pullToRefresh) { super.showLoading(pullToRefresh); RotateLoading rotateLoading = (RotateLoading) this.loadingView.findViewById(R.id.rl); if (!rotateLoading.isStart()) rotateLoading.start(); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/base/BasePresenter.java ================================================ package com.ittianyu.pocenter.common.base; import com.hannesdorfmann.mosby.mvp.MvpNullObjectBasePresenter; /** * Created by yu on 2016/11/25. */ public class BasePresenter extends MvpNullObjectBasePresenter implements BaseContract.Presenter{ protected BaseApplication application; @Override public void attachView(V view) { super.attachView(view); application = (BaseApplication) getView().getApp(); } @Override public BaseApplication getApp() { return application; } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/bean/ProjectBean.java ================================================ package com.ittianyu.pocenter.common.bean; import java.sql.Timestamp; /** * Created by yu on 2017/1/14. */ public class ProjectBean { public int id; public String projectId; public String title; public String description; public String price; public int type; public String cycle; public int people; public int status; public Timestamp time; public String reference; public String url; @Override public String toString() { return "ProjectBean{" + "projectId='" + projectId + '\'' + ", title='" + title + '\'' + ", description='" + description + '\'' + ", price='" + price + '\'' + ", type=" + type + ", cycle='" + cycle + '\'' + ", people=" + people + ", status=" + status + ", time=" + time + ", reference='" + reference + '\'' + ", url='" + url + '\'' + '}'; } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/tinker/FetchPatchHandler.java ================================================ package com.ittianyu.pocenter.common.tinker; import android.os.Handler; import android.os.Message; import com.tinkerpatch.sdk.TinkerPatch; /** * Created by zhangshaowen on 17/1/8. */ public class FetchPatchHandler extends Handler { public static final long HOUR_INTERVAL = 3600 * 1000; private long checkInterval; /** * 通过handler, 达到按照时间间隔轮训的效果 * @param hour */ public void fetchPatchWithInterval(int hour) { //设置TinkerPatch的时间间隔 TinkerPatch.with().setFetchPatchIntervalByHours(hour); checkInterval = hour * HOUR_INTERVAL; //立刻尝试去访问,检查是否有更新 sendEmptyMessage(0); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); //这里使用false即可 TinkerPatch.with().fetchPatchUpdate(false); //每隔一段时间都去访问后台, 增加10分钟的buffer时间 sendEmptyMessageDelayed(0, checkInterval + 10 * 60 * 1000); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/utils/CollectionUtils.java ================================================ package com.ittianyu.pocenter.common.utils; import java.util.Collection; /** * Created by yu on 2017/1/17. */ public class CollectionUtils { /** * check the collection is empty * @param collection * @return true if collection == null or size() == 0 */ public static boolean isEmpty(Collection collection) { if (null == collection || collection.isEmpty()) return true; return false; } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/utils/ConfigUtils.java ================================================ package com.ittianyu.pocenter.common.utils; import android.content.Context; import android.content.SharedPreferences; /** * Created by yu. * read and write config utils */ public class ConfigUtils { private static final String NAME = "config"; public static final String KEY_TYPE = "type"; /** * Put a key-value into config * @param context context * @param key the key * @param value the value */ public static void putString(Context context, String key, String value) { SharedPreferences sp = context.getSharedPreferences(NAME, Context.MODE_PRIVATE); SharedPreferences.Editor edit = sp.edit(); edit.putString(key, value) .commit(); } /** * Get value by key in config * @param context context * @param key the key * @param defaultValue if can't find the value of key, will return default value * @return value */ public static String getString(Context context, String key, String defaultValue) { SharedPreferences sp = context.getSharedPreferences(NAME, Context.MODE_PRIVATE); return sp.getString(key, defaultValue); } /** * Put a key-value into config * @param context context * @param key the key * @param value the value */ public static void putInt(Context context, String key, int value) { SharedPreferences sp = context.getSharedPreferences(NAME, Context.MODE_PRIVATE); SharedPreferences.Editor edit = sp.edit(); edit.putInt(key, value) .commit(); } /** * Get value by key in config * @param context context * @param key the key * @param defaultValue if can't find the value of key, will return default value * @return value */ public static int getInt(Context context, String key, int defaultValue) { SharedPreferences sp = context.getSharedPreferences(NAME, Context.MODE_PRIVATE); return sp.getInt(key, defaultValue); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/utils/RxUtils.java ================================================ package com.ittianyu.pocenter.common.utils; import java.util.NoSuchElementException; import io.reactivex.Observable; import io.reactivex.ObservableSource; import io.reactivex.ObservableTransformer; import io.reactivex.Observer; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; /** * Created by yu on 2016/12/2. */ public class RxUtils { /** * subscribeOn io * observeOn mainThread * * @param * @return */ public static ObservableTransformer netScheduler() { return new ObservableTransformer() { @Override public ObservableSource apply(Observable upstream) { return upstream.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } }; } /** * If the publish is empty, it wll run onError and throw a NoSuchElementException * @param * @return */ public static ObservableTransformer notEmptyOrError() { return new ObservableTransformer() { @Override public ObservableSource apply(Observable upstream) { return upstream.switchIfEmpty(new Observable() { @Override protected void subscribeActual(Observer observer) { observer.onError(new NoSuchElementException()); } }); } }; } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/common/utils/UnsafeOkHttpUtils.java ================================================ package com.ittianyu.pocenter.common.utils; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import okhttp3.OkHttpClient; /** * Created by yu on 2017/1/20. */ public class UnsafeOkHttpUtils { /** * don't verify certificate * @return */ public static OkHttpClient getClient() { try { // Create a trust manager that does not validate certificate chains final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { @Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) { } @Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) { } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[]{}; } } }; // Install the all-trusting trust manager final SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); // Create an ssl socket factory with our all-trusting manager final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.sslSocketFactory(sslSocketFactory); builder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); OkHttpClient okHttpClient = builder.build(); return okHttpClient; } catch (Exception e) { throw new RuntimeException(e); } } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/MainActivity.java ================================================ package com.ittianyu.pocenter.features; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v7.app.AppCompatActivity; import android.view.KeyEvent; import android.widget.Toast; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.databinding.ActMainBinding; import com.ittianyu.pocenter.features.find.FindFragment; import com.ittianyu.pocenter.features.home.HomeFragment; import com.ittianyu.pocenter.features.mime.MimeFragment; import com.ittianyu.pocenter.features.version.VersionUtils; import com.umeng.analytics.MobclickAgent; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { public static final long TIME_SPACE = 2000; private ActMainBinding bind; private VpAdapter adapter; // collections private List fragments;// used for ViewPager adapter private long clickTime; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); bind = DataBindingUtil.setContentView(this, R.layout.act_main); initData(); initView(); checkVersion(); } private void initData() { fragments = new ArrayList<>(3); // add fragments fragments.add(new HomeFragment()); fragments.add(new FindFragment()); fragments.add(new MimeFragment()); } private void initView() { // set bnve style bind.bnve.enableAnimation(false); // set adapter adapter = new VpAdapter(getSupportFragmentManager(), fragments); bind.vp.setOffscreenPageLimit(2); bind.vp.setAdapter(adapter); // binding with ViewPager bind.bnve.setupWithViewPager(bind.vp); } private void checkVersion() { VersionUtils.check(this); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_BACK: exit(); return true; } return super.onKeyDown(keyCode, event); } /** * if click time space < TIME_SPACE, app will exit */ private void exit() { if ((System.currentTimeMillis() - clickTime) > TIME_SPACE) { Toast.makeText(getApplicationContext(), R.string.exit_if_repeat, Toast.LENGTH_SHORT).show(); clickTime = System.currentTimeMillis(); return; } finish(); } /** * view pager adapter */ private static class VpAdapter extends FragmentPagerAdapter { private List data; public VpAdapter(FragmentManager fm, List data) { super(fm); this.data = data; } @Override public int getCount() { return data.size(); } @Override public Fragment getItem(int position) { return data.get(position); } } // 友盟统计 public void onResume() { super.onResume(); MobclickAgent.onResume(this); } public void onPause() { super.onPause(); MobclickAgent.onPause(this); } // 友盟统计 结束 } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/SplashActivity.java ================================================ package com.ittianyu.pocenter.features; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.common.base.BaseApplication; import com.ittianyu.pocenter.features.type.TypeActivity; import com.umeng.analytics.MobclickAgent; import java.util.concurrent.TimeUnit; import io.reactivex.Observable; import io.reactivex.functions.Consumer; public class SplashActivity extends AppCompatActivity { private static final long SHOW_TIME = 1000; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.act_splash); // wait for 1s to show splash activity Observable.just(new Object()) .delay(SHOW_TIME, TimeUnit.MILLISECONDS) .subscribe(new Consumer() { @Override public void accept(Object o) throws Exception { start(); } }); } /** * start load config */ private void start() { // check type if (!BaseApplication.getRepertories().isSettingTypes()) { // type is empty, need start type activity startActivity(new Intent(this, TypeActivity.class)); } else { // enter main activity startActivity(new Intent(this, MainActivity.class)); } finish(); } // 友盟统计 public void onResume() { super.onResume(); MobclickAgent.onResume(this); } public void onPause() { super.onPause(); MobclickAgent.onPause(this); } // 友盟统计 结束 } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/detail/DetailActivity.java ================================================ package com.ittianyu.pocenter.features.detail; import android.content.Intent; import android.databinding.DataBindingUtil; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.view.Menu; import android.view.MenuItem; import android.webkit.WebSettings; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.databinding.ActDetailBinding; import com.umeng.analytics.MobclickAgent; import cn.sharesdk.framework.ShareSDK; import cn.sharesdk.onekeyshare.OnekeyShare; public class DetailActivity extends AppCompatActivity { public static final String EXTRA_URL = "url"; public static final String EXTRA_TITLE = "title"; public static final String EXTRA_DESCRIPTION = "description"; private ActDetailBinding bind; private String url; private String title; private String description; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.act_detail); bind = DataBindingUtil.setContentView(this, R.layout.act_detail); Intent intent = getIntent(); // get url title description url = intent.getStringExtra(EXTRA_URL); title = intent.getStringExtra(EXTRA_TITLE); description = intent.getStringExtra(EXTRA_DESCRIPTION); // load website WebSettings settings = bind.wv.getSettings(); settings.setJavaScriptEnabled(true); bind.wv.loadUrl(url); // init action bar setSupportActionBar(bind.tb); ActionBar actionBar = getSupportActionBar(); actionBar.setTitle(""); if (!TextUtils.isEmpty(title))// set title bind.tvTitle.setText(title); // enable back button actionBar.setDisplayHomeAsUpEnabled(true); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_detail, menu); return super.onCreateOptionsMenu(menu); } /** * menu selected * * @param item * @return */ @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); break; case R.id.i_refresh: bind.wv.reload(); break; case R.id.i_open_in_browser: startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); break; case R.id.i_share: { showShare(); break; } } return super.onOptionsItemSelected(item); } private void showShare() { ShareSDK.initSDK(this); OnekeyShare oks = new OnekeyShare(); //关闭sso授权 oks.disableSSOWhenAuthorize(); // title标题,印象笔记、邮箱、信息、微信、人人网和QQ空间等使用 oks.setTitle(title); // titleUrl是标题的网络链接,QQ和QQ空间等使用 oks.setTitleUrl(url); // text是分享文本,所有平台都需要这个字段 oks.setText(description); // imagePath是图片的本地路径,Linked-In以外的平台都支持此参数 //oks.setImagePath("/sdcard/test.jpg");//确保SDcard下面存在此张图片 // url仅在微信(包括好友和朋友圈)中使用 oks.setUrl(url); // site是分享此内容的网站名称,仅在QQ空间使用 oks.setSite(getString(R.string.app_name)); // siteUrl是分享此内容的网站地址,仅在QQ空间使用 oks.setSiteUrl("https://www.ittianyu.com"); // 启动分享GUI oks.show(this); } // 友盟统计 public void onResume() { super.onResume(); MobclickAgent.onResume(this); } public void onPause() { super.onPause(); MobclickAgent.onPause(this); } // 友盟统计 结束 } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/find/FindAdapter.java ================================================ package com.ittianyu.pocenter.features.find; import com.chad.library.adapter.base.BaseQuickAdapter; import com.chad.library.adapter.base.BaseViewHolder; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.common.base.BaseApplication; import com.ittianyu.pocenter.common.bean.ProjectBean; import java.text.SimpleDateFormat; import java.util.List; import java.util.Locale; /** * Created by yu on 2017/1/17. */ public class FindAdapter extends BaseQuickAdapter { public FindAdapter(List data) { super(R.layout.item_find, data); } @Override protected void convert(BaseViewHolder baseViewHolder, ProjectBean projectBean) { baseViewHolder.setText(R.id.tv_title, projectBean.title); baseViewHolder.setText(R.id.tv_price, projectBean.price); // baseViewHolder.setText(R.id.tv_reference, projectBean.reference); baseViewHolder.setText(R.id.tv_type, transferType(projectBean.type)); baseViewHolder.setText(R.id.tv_description, projectBean.description); baseViewHolder.setText(R.id.tv_date, new SimpleDateFormat("yyyy-MM-dd", Locale.CHINESE).format(projectBean.time)); baseViewHolder.setText(R.id.tv_people_count, projectBean.people + mContext.getString(R.string.unit_people)); baseViewHolder.setText(R.id.tv_cycle, projectBean.cycle + mContext.getString(R.string.unit_day)); } /** * transfer type from code to string * @param type * @return */ private String transferType(int type) { List types = BaseApplication.getRepertories().getAllTypes(); if (type < types.size()) return types.get(type); return ""; } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/find/FindContract.java ================================================ package com.ittianyu.pocenter.features.find; import com.ittianyu.pocenter.common.base.BaseContract; import com.ittianyu.pocenter.common.bean.ProjectBean; import java.util.List; /** * Created by yu on 2017/1/17. */ public interface FindContract { interface View extends BaseContract.View> { void loadDataError(Throwable e, boolean pullToRefresh); void loadDataComplete(); void loadMore(); void addData(List data); void loadMoreError(Throwable e); void loadMoreComplete(); } interface Presenter extends BaseContract.Presenter { void loadData(boolean pullToRefresh); void loadMore(int start); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/find/FindFragment.java ================================================ package com.ittianyu.pocenter.features.find; import android.content.Intent; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.chad.library.adapter.base.BaseQuickAdapter; import com.chad.library.adapter.base.listener.OnItemClickListener; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.common.base.BaseFragment; import com.ittianyu.pocenter.common.bean.ProjectBean; import com.ittianyu.pocenter.common.utils.CollectionUtils; import com.ittianyu.pocenter.databinding.FragFindBinding; import com.ittianyu.pocenter.features.detail.DetailActivity; import com.ittianyu.pocenter.features.search.SearchActivity; import com.orhanobut.logger.Logger; import java.util.ArrayList; import java.util.List; /** * Created by yu on 2017/1/13. */ public class FindFragment extends BaseFragment, FindContract.View, FindContract.Presenter> implements FindContract.View { private FragFindBinding bind; private FindAdapter findAdapter; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { // Logger.d("onCreateView"); return View.inflate(getContext(), R.layout.frag_find, null); } @Override public FindContract.Presenter createPresenter() { return new FindPresenter(); } @Override protected void initView(View view) { bind = DataBindingUtil.bind(view); // init recycler view findAdapter = new FindAdapter(new ArrayList(0)); bind.rv.setAdapter(findAdapter); bind.rv.setLayoutManager(new LinearLayoutManager(getContext())); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL); dividerItemDecoration.setDrawable(getResources().getDrawable(R.drawable.shape_drive_line)); bind.rv.addItemDecoration(dividerItemDecoration); initEvent(); } /** * set listeners */ private void initEvent() { // refresh listener bind.vContent.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { loadData(true); } }); // load more listener findAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() { @Override public void onLoadMoreRequested() { bind.rv.post(new Runnable() { @Override public void run() { loadMore(); } }); } }); // set listener to start search bind.tb.findViewById(R.id.ll_root).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(getContext(), SearchActivity.class)); } }); // item click listener bind.rv.addOnItemTouchListener(new OnItemClickListener() { @Override public void SimpleOnItemClick(BaseQuickAdapter baseQuickAdapter, View view, int i) { // get item url ProjectBean project = (ProjectBean) baseQuickAdapter.getItem(i); // start detail activity Intent intent = new Intent(getContext(), DetailActivity.class); intent.putExtra(DetailActivity.EXTRA_URL, project.url); intent.putExtra(DetailActivity.EXTRA_TITLE, project.title); intent.putExtra(DetailActivity.EXTRA_DESCRIPTION, project.description); startActivity(intent); } }); } @Override public void loadData(boolean pullToRefresh) { // disable load more when reload data or first load findAdapter.setEnableLoadMore(false); // show loading showLoading(pullToRefresh); presenter.loadData(pullToRefresh); Logger.d("start load data"); } @Override public void setData(List data) { if (CollectionUtils.isEmpty(data)) { showEmpty(); } else { showContent(); } findAdapter.setNewData(data); Logger.d("set data"); loadDataComplete(); } @Override public void loadDataError(Throwable e, boolean pullToRefresh) { showError(e, pullToRefresh); Logger.d("load data error"); loadDataComplete(); } @Override public void loadDataComplete() { // enable load more after reload completed findAdapter.setEnableLoadMore(true); bind.vContent.setRefreshing(false); Logger.d("load data complete"); } @Override public void loadMore() { // disable refresh when load more bind.vContent.setEnabled(false); presenter.loadMore(findAdapter.getData().size()); Logger.d("start load more"); } @Override public void addData(List data) { if (CollectionUtils.isEmpty(data)) { // no more data findAdapter.loadMoreEnd(); } else { findAdapter.loadMoreComplete(); } findAdapter.addData(data); Logger.d("add data"); loadMoreComplete(); } @Override public void loadMoreError(Throwable e) { // showError(e, false); findAdapter.loadMoreFail(); Logger.d("load more error"); loadMoreComplete(); } @Override public void loadMoreComplete() { // enable reload after load more completed bind.vContent.setEnabled(true); Logger.d("load more complete"); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/find/FindPresenter.java ================================================ package com.ittianyu.pocenter.features.find; import com.ittianyu.pocenter.common.api.RemoteApi; import com.ittianyu.pocenter.common.base.BasePresenter; import com.ittianyu.pocenter.common.bean.ProjectBean; import java.util.List; import io.reactivex.functions.Consumer; /** * Created by yu on 2017/1/17. */ public class FindPresenter extends BasePresenter implements FindContract.Presenter { private static final int COUNT = 20; @Override public void loadData(final boolean pullToRefresh) { application.getRepertories() .getList(0, COUNT, null, RemoteApi.Status.RECRUITING, null, pullToRefresh) .subscribe(new Consumer>() { @Override public void accept(List projectBeen) throws Exception { getView().setData(projectBeen); } }, new Consumer() { @Override public void accept(Throwable throwable) throws Exception { getView().loadDataError(throwable, pullToRefresh); } }); } @Override public void loadMore(int start) { application.getRepertories() .getList(start, COUNT, null, RemoteApi.Status.RECRUITING, null, false) .subscribe(new Consumer>() { @Override public void accept(List projectBeen) throws Exception { getView().addData(projectBeen); } }, new Consumer() { @Override public void accept(Throwable throwable) throws Exception { getView().loadMoreError(throwable); } }); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/home/HomeAdapter.java ================================================ package com.ittianyu.pocenter.features.home; import com.chad.library.adapter.base.BaseQuickAdapter; import com.chad.library.adapter.base.BaseViewHolder; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.common.base.BaseApplication; import com.ittianyu.pocenter.common.bean.ProjectBean; import java.text.SimpleDateFormat; import java.util.List; import java.util.Locale; /** * Created by yu on 2017/1/17. */ public class HomeAdapter extends BaseQuickAdapter { public HomeAdapter(List data) { super(R.layout.item_home, data); } @Override protected void convert(BaseViewHolder baseViewHolder, ProjectBean projectBean) { baseViewHolder.setText(R.id.tv_title, projectBean.title); baseViewHolder.setText(R.id.tv_price, projectBean.price); baseViewHolder.setText(R.id.tv_reference, projectBean.reference); baseViewHolder.setText(R.id.tv_type, transferType(projectBean.type)); baseViewHolder.setText(R.id.tv_description, projectBean.description); baseViewHolder.setText(R.id.tv_date, new SimpleDateFormat("yyyy-MM-dd", Locale.CHINESE).format(projectBean.time)); baseViewHolder.setText(R.id.tv_people_count, projectBean.people + mContext.getString(R.string.unit_people)); baseViewHolder.setText(R.id.tv_cycle, projectBean.cycle + mContext.getString(R.string.unit_day)); } /** * transfer type from code to string * @param type * @return */ private String transferType(int type) { List types = BaseApplication.getRepertories().getAllTypes(); if (type < types.size()) return types.get(type); return ""; } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/home/HomeContract.java ================================================ package com.ittianyu.pocenter.features.home; import com.ittianyu.pocenter.common.base.BaseContract; import com.ittianyu.pocenter.common.bean.ProjectBean; import java.util.List; /** * Created by yu on 2017/1/17. */ public interface HomeContract { interface View extends BaseContract.View> { void loadDataError(Throwable e, boolean pullToRefresh); void loadDataComplete(); void loadMore(); void addData(List data); void loadMoreError(Throwable e); void loadMoreComplete(); } interface Presenter extends BaseContract.Presenter { void loadData(boolean pullToRefresh); void loadMore(int start); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/home/HomeFragment.java ================================================ package com.ittianyu.pocenter.features.home; import android.content.Intent; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.chad.library.adapter.base.BaseQuickAdapter; import com.chad.library.adapter.base.listener.OnItemClickListener; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.common.base.BaseFragment; import com.ittianyu.pocenter.common.bean.ProjectBean; import com.ittianyu.pocenter.common.utils.CollectionUtils; import com.ittianyu.pocenter.databinding.FragHomeBinding; import com.ittianyu.pocenter.features.detail.DetailActivity; import com.orhanobut.logger.Logger; import java.util.ArrayList; import java.util.List; /** * Created by yu on 2017/1/13. */ public class HomeFragment extends BaseFragment, HomeContract.View, HomeContract.Presenter> implements HomeContract.View { private FragHomeBinding bind; private HomeAdapter homeAdapter; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { // Logger.d("onCreateView"); return View.inflate(getContext(), R.layout.frag_home, null); } @Override public HomeContract.Presenter createPresenter() { return new HomePresenter(); } @Override protected void initView(View view) { bind = DataBindingUtil.bind(view); // init recycler view homeAdapter = new HomeAdapter(new ArrayList(0)); bind.rv.setAdapter(homeAdapter); bind.rv.setLayoutManager(new LinearLayoutManager(getContext())); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL); dividerItemDecoration.setDrawable(getResources().getDrawable(R.drawable.shape_drive_line)); bind.rv.addItemDecoration(dividerItemDecoration); initEvent(); } /** * set listeners */ private void initEvent() { // refresh listener bind.vContent.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { loadData(true); } }); // load more listener homeAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() { @Override public void onLoadMoreRequested() { bind.rv.post(new Runnable() { @Override public void run() { loadMore(); } }); } }); // item click listener bind.rv.addOnItemTouchListener(new OnItemClickListener() { @Override public void SimpleOnItemClick(BaseQuickAdapter baseQuickAdapter, View view, int i) { // get item url ProjectBean project = (ProjectBean) baseQuickAdapter.getItem(i); // start detail activity Intent intent = new Intent(getContext(), DetailActivity.class); intent.putExtra(DetailActivity.EXTRA_URL, project.url); intent.putExtra(DetailActivity.EXTRA_TITLE, project.title); intent.putExtra(DetailActivity.EXTRA_DESCRIPTION, project.description); startActivity(intent); } }); } @Override public void loadData(boolean pullToRefresh) { // disable load more when reload data or first load homeAdapter.setEnableLoadMore(false); // show loading showLoading(pullToRefresh); presenter.loadData(pullToRefresh); Logger.d("start load data"); } @Override public void setData(List data) { if (CollectionUtils.isEmpty(data)) { showEmpty(); } else { showContent(); } homeAdapter.setNewData(data); Logger.d("set data"); loadDataComplete(); } @Override public void loadDataError(Throwable e, boolean pullToRefresh) { showError(e, pullToRefresh); Logger.d("load data error"); loadDataComplete(); } @Override public void loadDataComplete() { // enable load more after reload completed homeAdapter.setEnableLoadMore(true); bind.vContent.setRefreshing(false); Logger.d("load data complete"); } @Override public void loadMore() { // disable refresh when load more bind.vContent.setEnabled(false); presenter.loadMore(homeAdapter.getData().size()); Logger.d("start load more"); } @Override public void addData(List data) { if (CollectionUtils.isEmpty(data)) { // no more data homeAdapter.loadMoreEnd(); } else { homeAdapter.loadMoreComplete(); } homeAdapter.addData(data); Logger.d("add data"); loadMoreComplete(); } @Override public void loadMoreError(Throwable e) { // showError(e, false); homeAdapter.loadMoreFail(); Logger.d("load more error"); loadMoreComplete(); } @Override public void loadMoreComplete() { // enable reload after load more completed bind.vContent.setEnabled(true); Logger.d("load more complete"); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/home/HomePresenter.java ================================================ package com.ittianyu.pocenter.features.home; import com.ittianyu.pocenter.common.api.RemoteApi; import com.ittianyu.pocenter.common.base.BaseApplication; import com.ittianyu.pocenter.common.base.BasePresenter; import com.ittianyu.pocenter.common.bean.ProjectBean; import java.util.List; import io.reactivex.functions.Consumer; /** * Created by yu on 2017/1/17. */ public class HomePresenter extends BasePresenter implements HomeContract.Presenter { private static final int COUNT = 20; private int[] types; public HomePresenter() { loadTypes(); } /** * load user selected types from config */ private void loadTypes() { // load types types = BaseApplication.getRepertories().getTypes(); } @Override public void loadData(final boolean pullToRefresh) { // if refresh data, update types first if (pullToRefresh) loadTypes(); application.getRepertories() .getList(0, COUNT, types, RemoteApi.Status.RECRUITING, null, pullToRefresh) .subscribe(new Consumer>() { @Override public void accept(List projectBeen) throws Exception { getView().setData(projectBeen); } }, new Consumer() { @Override public void accept(Throwable throwable) throws Exception { getView().loadDataError(throwable, pullToRefresh); } }); } @Override public void loadMore(int start) { application.getRepertories() .getList(start, COUNT, types, RemoteApi.Status.RECRUITING, null, false) .subscribe(new Consumer>() { @Override public void accept(List projectBeen) throws Exception { getView().addData(projectBeen); } }, new Consumer() { @Override public void accept(Throwable throwable) throws Exception { getView().loadMoreError(throwable); } }); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/mime/MimeFragment.java ================================================ package com.ittianyu.pocenter.features.mime; import android.content.Context; import android.content.Intent; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.app.AlertDialog; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.ittianyu.pocenter.BuildConfig; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.databinding.FragMimeBinding; import com.ittianyu.pocenter.features.type.TypeActivity; import com.ittianyu.pocenter.features.version.VersionUtils; /** * Created by yu on 2017/1/13. */ public class MimeFragment extends Fragment { private FragMimeBinding bind; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return View.inflate(getContext(), R.layout.frag_mime, null); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); initView(view); initEvent(); } private void initView(View view) { bind = DataBindingUtil.bind(view); } private void initEvent() { // tag manager bind.llTagManager.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(getContext(), TypeActivity.class)); } }); // about bind.llAbout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Context context = getContext(); new AlertDialog.Builder(context) .setTitle(context.getString(R.string.app_name) + " (" + BuildConfig.VERSION_NAME + ")") .setMessage(R.string.tips_about_us) .setPositiveButton(R.string.ok, null) .show(); } }); // version check bind.llVersionCheck.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { VersionUtils.check(getContext(), true); } }); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/search/SearchActivity.java ================================================ package com.ittianyu.pocenter.features.search; import android.content.Intent; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.LinearLayoutManager; import android.text.TextUtils; import android.view.View; import android.widget.TextView; import com.arlib.floatingsearchview.FloatingSearchView; import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion; import com.chad.library.adapter.base.BaseQuickAdapter; import com.chad.library.adapter.base.listener.OnItemClickListener; import com.ittianyu.mvp.lcee.Lcee; import com.ittianyu.mvp.lcee.MvpLceeActivity; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.common.bean.ProjectBean; import com.ittianyu.pocenter.common.utils.CollectionUtils; import com.ittianyu.pocenter.databinding.ActSearchBinding; import com.ittianyu.pocenter.features.detail.DetailActivity; import com.orhanobut.logger.Logger; import com.umeng.analytics.MobclickAgent; import com.victor.loading.rotate.RotateLoading; import java.util.ArrayList; import java.util.List; /** * Created by yu on 2017/1/13. */ @Lcee(loadingViewId = R.id.v_loading, contentViewId = R.id.v_content, errorViewId = R.id.v_error, emptyViewId = R.id.v_empty) public class SearchActivity extends MvpLceeActivity, SearchContract.View, SearchContract.Presenter> implements SearchContract.View { private ActSearchBinding bind; private SearchAdapter searchAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); bind = DataBindingUtil.setContentView(this, R.layout.act_search); initView(); } @Override protected String getErrorMessage(Throwable e, boolean pullToRefresh) { Logger.e(e, ""); return pullToRefresh ? getString(R.string.failed_to_refresh) : getString(R.string.failed_to_load_click_to_reload); } @Override protected void onSetErrorViewText(View errorView, String errorMsg) { TextView tv = (TextView) errorView.findViewById(R.id.tv); tv.setText(errorMsg); } @Override public void showLoading(boolean pullToRefresh) { super.showLoading(pullToRefresh); RotateLoading rotateLoading = (RotateLoading) this.loadingView.findViewById(R.id.rl); if (!rotateLoading.isStart()) rotateLoading.start(); } @Override public SearchContract.Presenter createPresenter() { return new SearchPresenter(); } protected void initView() { // init recycler view searchAdapter = new SearchAdapter(new ArrayList(0)); bind.rv.setAdapter(searchAdapter); bind.rv.setLayoutManager(new LinearLayoutManager(this)); // bind.rv.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL)); bind.fsv.setSearchFocused(true); initEvent(); showContent(); } /** * set listeners */ private void initEvent() { // refresh listener bind.vContent.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { loadData(true); } }); // load more listener searchAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() { @Override public void onLoadMoreRequested() { bind.rv.post(new Runnable() { @Override public void run() { loadMore(); } }); } }); // item click listener bind.rv.addOnItemTouchListener(new OnItemClickListener() { @Override public void SimpleOnItemClick(BaseQuickAdapter baseQuickAdapter, View view, int i) { // get item url ProjectBean project = (ProjectBean) baseQuickAdapter.getItem(i); // start detail activity Intent intent = new Intent(SearchActivity.this, DetailActivity.class); intent.putExtra(DetailActivity.EXTRA_URL, project.url); intent.putExtra(DetailActivity.EXTRA_TITLE, project.title); intent.putExtra(DetailActivity.EXTRA_DESCRIPTION, project.description); startActivity(intent); } }); // search listener bind.fsv.setOnSearchListener(new FloatingSearchView.OnSearchListener() { @Override public void onSuggestionClicked(SearchSuggestion searchSuggestion) { } @Override public void onSearchAction(String currentQuery) { if (!TextUtils.isEmpty(currentQuery)) { presenter.setSearchString(currentQuery); loadData(false); } } }); } @Override public void loadData(boolean pullToRefresh) { // disable load more when reload data or first load searchAdapter.setEnableLoadMore(false); // show loading showLoading(pullToRefresh); presenter.loadData(pullToRefresh); Logger.d("start load data"); } @Override public void setData(List data) { if (CollectionUtils.isEmpty(data)) { showEmpty(); } else { showContent(); } searchAdapter.setNewData(data); bind.rv.scrollToPosition(0); Logger.d("set data"); loadDataComplete(); } @Override public void loadDataError(Throwable e, boolean pullToRefresh) { showError(e, pullToRefresh); Logger.d("load data error"); loadDataComplete(); } @Override public void loadDataComplete() { // enable load more after reload completed searchAdapter.setEnableLoadMore(true); bind.vContent.setRefreshing(false); Logger.d("load data complete"); } @Override public void loadMore() { // disable refresh when load more bind.vContent.setEnabled(false); presenter.loadMore(searchAdapter.getData().size()); Logger.d("start load more"); } @Override public void addData(List data) { if (CollectionUtils.isEmpty(data)) { // no more data searchAdapter.loadMoreEnd(); } else { searchAdapter.loadMoreComplete(); } searchAdapter.addData(data); Logger.d("add data"); loadMoreComplete(); } @Override public void loadMoreError(Throwable e) { // showError(e, false); searchAdapter.loadMoreFail(); Logger.d("load more error"); loadMoreComplete(); } @Override public void loadMoreComplete() { // enable reload after load more completed bind.vContent.setEnabled(true); Logger.d("load more complete"); } @Override public T getApp() { return (T) getApplication(); } // 友盟统计 public void onResume() { super.onResume(); MobclickAgent.onResume(this); } public void onPause() { super.onPause(); MobclickAgent.onPause(this); } // 友盟统计 结束 } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/search/SearchAdapter.java ================================================ package com.ittianyu.pocenter.features.search; import com.chad.library.adapter.base.BaseQuickAdapter; import com.chad.library.adapter.base.BaseViewHolder; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.common.base.BaseApplication; import com.ittianyu.pocenter.common.bean.ProjectBean; import java.text.SimpleDateFormat; import java.util.List; import java.util.Locale; /** * Created by yu on 2017/1/17. */ public class SearchAdapter extends BaseQuickAdapter { public SearchAdapter(List data) { super(R.layout.item_search, data); } @Override protected void convert(BaseViewHolder baseViewHolder, ProjectBean projectBean) { baseViewHolder.setText(R.id.tv_title, projectBean.title); baseViewHolder.setText(R.id.tv_price, projectBean.price); // baseViewHolder.setText(R.id.tv_reference, projectBean.reference); // baseViewHolder.setText(R.id.tv_type, transferType(projectBean.type)); baseViewHolder.setText(R.id.tv_description, projectBean.description); baseViewHolder.setText(R.id.tv_date, new SimpleDateFormat("yyyy-MM-dd", Locale.CHINESE).format(projectBean.time)); baseViewHolder.setText(R.id.tv_people_count, projectBean.people + mContext.getString(R.string.unit_people)); baseViewHolder.setText(R.id.tv_cycle, projectBean.cycle + mContext.getString(R.string.unit_day)); } /** * transfer type from code to string * @param type * @return */ private String transferType(int type) { List types = BaseApplication.getRepertories().getAllTypes(); if (type < types.size()) return types.get(type); return ""; } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/search/SearchContract.java ================================================ package com.ittianyu.pocenter.features.search; import com.ittianyu.pocenter.common.base.BaseContract; import com.ittianyu.pocenter.common.bean.ProjectBean; import java.util.List; /** * Created by yu on 2017/1/17. */ public interface SearchContract { interface View extends BaseContract.View> { void loadDataError(Throwable e, boolean pullToRefresh); void loadDataComplete(); void loadMore(); void addData(List data); void loadMoreError(Throwable e); void loadMoreComplete(); } interface Presenter extends BaseContract.Presenter { void loadData(boolean pullToRefresh); void loadMore(int start); void setSearchString(String search); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/search/SearchPresenter.java ================================================ package com.ittianyu.pocenter.features.search; import com.ittianyu.pocenter.common.api.RemoteApi; import com.ittianyu.pocenter.common.base.BasePresenter; import com.ittianyu.pocenter.common.bean.ProjectBean; import com.orhanobut.logger.Logger; import java.util.List; import io.reactivex.functions.Consumer; /** * Created by yu on 2017/1/17. */ public class SearchPresenter extends BasePresenter implements SearchContract.Presenter { private static final int COUNT = 20; private String[] keywords; @Override public void loadData(final boolean pullToRefresh) { application.getRepertories() .getList(0, COUNT, null, RemoteApi.Status.RECRUITING, keywords, pullToRefresh) .subscribe(new Consumer>() { @Override public void accept(List projectBeen) throws Exception { getView().setData(projectBeen); } }, new Consumer() { @Override public void accept(Throwable throwable) throws Exception { getView().loadDataError(throwable, pullToRefresh); } }); } @Override public void loadMore(int start) { application.getRepertories() .getList(start, COUNT, null, RemoteApi.Status.RECRUITING, keywords, false) .subscribe(new Consumer>() { @Override public void accept(List projectBeen) throws Exception { getView().addData(projectBeen); } }, new Consumer() { @Override public void accept(Throwable throwable) throws Exception { getView().loadMoreError(throwable); } }); } @Override public void setSearchString(String search) { keywords = search.split(" "); Logger.d(keywords); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/type/TypeActivity.java ================================================ package com.ittianyu.pocenter.features.type; import android.content.Intent; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.annotation.NonNull; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.TextView; import android.widget.Toast; import com.hannesdorfmann.mosby.mvp.MvpActivity; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.common.base.BaseApplication; import com.ittianyu.pocenter.databinding.ActTypeBinding; import com.ittianyu.pocenter.features.MainActivity; import com.orhanobut.logger.Logger; import com.umeng.analytics.MobclickAgent; import com.zhy.view.flowlayout.FlowLayout; import com.zhy.view.flowlayout.TagAdapter; import java.util.HashSet; import java.util.List; import java.util.Set; public class TypeActivity extends MvpActivity implements TypeContract.View { private ActTypeBinding bind; private MyTagAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // setContentView(R.layout.act_type); bind = DataBindingUtil.setContentView(this, R.layout.act_type); initView(); presenter.loadData(); initEvent(); } @NonNull @Override public TypeContract.Presenter createPresenter() { return new TypePresenter(); } private void initView() { // init action bar setSupportActionBar(bind.tb); } private void initEvent() { bind.btnOk.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Set list = bind.tfl.getSelectedList(); Logger.d(list); if (list.isEmpty()) { Toast.makeText(TypeActivity.this, R.string.toast_select_one_or_more_type, Toast.LENGTH_SHORT).show(); return; } // save selected types BaseApplication.getRepertories().setTypes(list); // start activity if (presenter.isFirstSetting()) startActivity(new Intent(TypeActivity.this, MainActivity.class)); finish(); } }); } @Override public void setData(List data, int[] types) { adapter = new MyTagAdapter(data); bind.tfl.setAdapter(adapter); // set selected list if (null != types) adapter.setSelectedList(types); } /** * create menu * @param menu * @return */ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_type, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.i_select_all: selectAll(); break; case R.id.i_cancel_all: cancelAll(); break; } return super.onOptionsItemSelected(item); } /** * cancel all selected item */ private void cancelAll() { adapter.setSelectedList(new HashSet(0)); } /** * select all item */ private void selectAll() { int count = adapter.getCount(); int[] list = new int[count]; for (int i = 0; i < count; i++) { list[i] = i; } adapter.setSelectedList(list); } private static class MyTagAdapter extends TagAdapter { public MyTagAdapter(List data) { super(data); } @Override public View getView(FlowLayout parent, int position, String s) { TextView tv = (TextView) LayoutInflater.from(parent.getContext()).inflate(R.layout.view_type, parent, false); tv.setText(s); return tv; } } // 友盟统计 public void onResume() { super.onResume(); MobclickAgent.onResume(this); } public void onPause() { super.onPause(); MobclickAgent.onPause(this); } // 友盟统计 结束 } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/type/TypeContract.java ================================================ package com.ittianyu.pocenter.features.type; import com.hannesdorfmann.mosby.mvp.MvpPresenter; import com.hannesdorfmann.mosby.mvp.MvpView; import java.util.List; /** * Created by yu on 2017/1/17. */ public interface TypeContract { interface View extends MvpView { void setData(List data, int[] types); } interface Presenter extends MvpPresenter { void loadData(); boolean isFirstSetting(); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/type/TypePresenter.java ================================================ package com.ittianyu.pocenter.features.type; import com.hannesdorfmann.mosby.mvp.MvpNullObjectBasePresenter; import com.ittianyu.pocenter.common.api.Repertories; import com.ittianyu.pocenter.common.base.BaseApplication; import java.util.List; /** * Created by yu on 2017/1/17. */ public class TypePresenter extends MvpNullObjectBasePresenter implements TypeContract.Presenter { private int[] types; @Override public void loadData() { // load all types Repertories repertories = BaseApplication.getRepertories(); List allTypes = repertories.getAllTypes(); // load selected types types = repertories.getTypes(); // set data getView().setData(allTypes, types); } @Override public boolean isFirstSetting() { return null == types; } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/version/CheckVersionService.java ================================================ package com.ittianyu.pocenter.features.version; import android.content.Intent; import android.os.IBinder; import android.widget.Toast; import com.allenliu.versionchecklib.AVersionService; import com.google.gson.Gson; import com.ittianyu.pocenter.BuildConfig; import com.ittianyu.pocenter.R; import com.ittianyu.pocenter.common.utils.UnsafeOkHttpUtils; import com.zhy.http.okhttp.OkHttpUtils; public class CheckVersionService extends AVersionService { public static final String SHOW_LAST = "showLast"; private boolean showLast = false; public CheckVersionService() { OkHttpUtils.initClient(UnsafeOkHttpUtils.getClient()); } @Override public int onStartCommand(Intent intent, int flags, int startId) { showLast = intent.getBooleanExtra(SHOW_LAST, showLast); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onResponses(AVersionService service, String response) { Gson gson = new Gson(); VersionBean versionBean = gson.fromJson(response, VersionBean.class); if (versionBean.versionCode > BuildConfig.VERSION_CODE) { //传入下载地址,以及版本更新消息 service.showVersionDialog(versionBean.apkUrl, versionBean.changeLog); } else { if (showLast) Toast.makeText(service.getApplicationContext(), R.string.tips_already_last_version, Toast.LENGTH_SHORT).show(); //由于是回调方法,当不进行版本升级时,需要手动关闭service。需要进行版本升级时,由库管理生命周期 stopSelf(); } } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/version/VersionBean.java ================================================ package com.ittianyu.pocenter.features.version; /** * Created by yu on 2017/1/19. */ public class VersionBean { /* "versionCode": 2, "versionName": "1.1", "apkUrl": "http://oh0vbg8a6.bkt.clouddn.com/app-debug.apk", "updateTitle": "更新提示", "changeLog":"1.修复xxx Bug;2.更新了某某UI界面." */ public int versionCode; public String versionName; public String apkUrl; public String updateTitle; public String changeLog; } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/version/VersionUtils.java ================================================ package com.ittianyu.pocenter.features.version; import android.content.Context; import android.content.Intent; import com.allenliu.versionchecklib.VersionParams; import com.ittianyu.pocenter.common.api.Repertories; /** * Created by yu on 2017/1/19. */ public class VersionUtils { /** * check version * @param context */ public static void check(Context context) { check(context, false); } /** * check version * @param context * @param showLast it will show a tip tell user the version is last if true. */ public static void check(Context context, boolean showLast) { VersionParams versionField = new VersionParams() //是否强制升级,默认false .setIsForceUpdate(false) //当版本接口请求失败时,service会根据设定的间隔时间继续请求版本接口, // 直到手动关闭service或者接口请求成功,不填默认10s // .setPauseRequestTime(requestTime) //接口地址,必填 .setRequestUrl(Repertories.URL_BASE + "version.json") //自定service包名,必须填写用于开启service .setVersionServiceName(CheckVersionService.class.getName()); Intent intent = new Intent(context, CheckVersionService.class); intent.putExtra("versionField", versionField); intent.putExtra(CheckVersionService.SHOW_LAST, showLast); context.startService(intent); } } ================================================ FILE: app/src/main/java/com/ittianyu/pocenter/features/wxapi/WXEntryActivity.java ================================================ /* * 官网地站:http://www.mob.com * 技术支持QQ: 4006852216 * 官方微信:ShareSDK (如果发布新版本的话,我们将会第一时间通过微信将版本更新内容推送给您。如果使用过程中有任何问题,也可以通过微信与我们取得联系,我们将会在24小时内给予回复) * * Copyright (c) 2013年 mob.com. All rights reserved. */ package com.ittianyu.pocenter.features.wxapi; import android.content.Intent; import android.widget.Toast; import cn.sharesdk.wechat.utils.WXAppExtendObject; import cn.sharesdk.wechat.utils.WXMediaMessage; import cn.sharesdk.wechat.utils.WechatHandlerActivity; /** 微信客户端回调activity示例 */ public class WXEntryActivity extends WechatHandlerActivity { /** * 处理微信发出的向第三方应用请求app message *

* 在微信客户端中的聊天页面有“添加工具”,可以将本应用的图标添加到其中 * 此后点击图标,下面的代码会被执行。Demo仅仅只是打开自己而已,但你可 * 做点其他的事情,包括根本不打开任何页面 */ public void onGetMessageFromWXReq(WXMediaMessage msg) { if (msg != null) { Intent iLaunchMyself = getPackageManager().getLaunchIntentForPackage(getPackageName()); startActivity(iLaunchMyself); } } /** * 处理微信向第三方应用发起的消息 *

* 此处用来接收从微信发送过来的消息,比方说本demo在wechatpage里面分享 * 应用时可以不分享应用文件,而分享一段应用的自定义信息。接受方的微信 * 客户端会通过这个方法,将这个信息发送回接收方手机上的本demo中,当作 * 回调。 *

* 本Demo只是将信息展示出来,但你可做点其他的事情,而不仅仅只是Toast */ public void onShowMessageFromWXReq(WXMediaMessage msg) { if (msg != null && msg.mediaObject != null && (msg.mediaObject instanceof WXAppExtendObject)) { WXAppExtendObject obj = (WXAppExtendObject) msg.mediaObject; Toast.makeText(this, obj.extInfo, Toast.LENGTH_SHORT).show(); } } } ================================================ FILE: app/src/main/res/color/selector_item_color.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_about.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_cycle.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_date.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_empty.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_error.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_find.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_github.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_home.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_logo.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_mine.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_people.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_share.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_type.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ic_version_check.xml ================================================ ================================================ FILE: app/src/main/res/drawable/selector_button.xml ================================================ ================================================ FILE: app/src/main/res/drawable/selector_item.xml ================================================ ================================================ FILE: app/src/main/res/drawable/selector_type.xml ================================================ ================================================ FILE: app/src/main/res/drawable/shape_button_normal.xml ================================================ ================================================ FILE: app/src/main/res/drawable/shape_button_pressed.xml ================================================ ================================================ FILE: app/src/main/res/drawable/shape_drive_line.xml ================================================ ================================================ FILE: app/src/main/res/drawable/shape_type_checked.xml ================================================ ================================================ FILE: app/src/main/res/drawable/shape_type_normal.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ssdk_oks_classic_platform_cell_back.xml ================================================ ================================================ FILE: app/src/main/res/drawable/ssdk_oks_classic_progressbar.xml ================================================ ================================================ FILE: app/src/main/res/drawable-v21/selector_button.xml ================================================ ================================================ FILE: app/src/main/res/drawable-v21/selector_item.xml ================================================ ================================================ FILE: app/src/main/res/layout/act_detail.xml ================================================ ================================================ FILE: app/src/main/res/layout/act_main.xml ================================================ ================================================ FILE: app/src/main/res/layout/act_search.xml ================================================ ================================================ FILE: app/src/main/res/layout/act_splash.xml ================================================ ================================================ FILE: app/src/main/res/layout/act_type.xml ================================================