├── app
├── .gitignore
├── my.jks
├── src
│ ├── main
│ │ ├── ic_launcher-web.png
│ │ ├── res
│ │ │ ├── mipmap-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_nav_icon.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── values
│ │ │ │ ├── ids.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── colors.xml
│ │ │ │ ├── styles.xml
│ │ │ │ └── strings.xml
│ │ │ ├── xml
│ │ │ │ └── network_security_config.xml
│ │ │ ├── values-w820dp
│ │ │ │ └── dimens.xml
│ │ │ ├── drawable
│ │ │ │ ├── shape_bg_about_text_green.xml
│ │ │ │ ├── shape_bg_about_text_purple.xml
│ │ │ │ ├── shape_bg_about_text.xml
│ │ │ │ ├── ic_menu_weather.xml
│ │ │ │ ├── ic_menu_tools.xml
│ │ │ │ ├── ic_menu_about.xml
│ │ │ │ ├── ic_fab_love.xml
│ │ │ │ ├── ic_menu_news.xml
│ │ │ │ ├── ic_menu_sister.xml
│ │ │ │ ├── ic_menu_subway.xml
│ │ │ │ ├── ic_menu_setting.xml
│ │ │ │ └── ic_launcher_background.xml
│ │ │ ├── anim
│ │ │ │ ├── anim_fab_out.xml
│ │ │ │ └── anim_fab_in.xml
│ │ │ ├── layout
│ │ │ │ ├── content_main.xml
│ │ │ │ ├── item_mz.xml
│ │ │ │ ├── fragment_news.xml
│ │ │ │ ├── fragment_tools.xml
│ │ │ │ ├── fragment_subway.xml
│ │ │ │ ├── fragment_weather.xml
│ │ │ │ ├── activity_picture_detail.xml
│ │ │ │ ├── app_bar_main.xml
│ │ │ │ ├── activity_main.xml
│ │ │ │ ├── activity_splash.xml
│ │ │ │ ├── activity_about.xml
│ │ │ │ ├── activity_setting.xml
│ │ │ │ ├── fragment_mz_content.xml
│ │ │ │ ├── nav_header_main.xml
│ │ │ │ ├── fragment_little_sister.xml
│ │ │ │ ├── fragment_about.xml
│ │ │ │ └── fragment_setting.xml
│ │ │ └── menu
│ │ │ │ └── activity_main_drawer.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── coderpig
│ │ │ │ └── drysisters
│ │ │ │ ├── utils
│ │ │ │ ├── ResUtils.java
│ │ │ │ ├── SizeUtils.java
│ │ │ │ ├── ToastUtils.java
│ │ │ │ ├── NetworkUtils.java
│ │ │ │ ├── PackageUtils.java
│ │ │ │ └── RxSchedulers.java
│ │ │ │ ├── DryConstant.java
│ │ │ │ ├── DrySisterApp.java
│ │ │ │ ├── ui
│ │ │ │ ├── fragment
│ │ │ │ │ ├── NewsFragment.java
│ │ │ │ │ ├── ToolsFragment.java
│ │ │ │ │ ├── SubwayFragment.java
│ │ │ │ │ ├── WeatherFragment.java
│ │ │ │ │ ├── AboutFragment.java
│ │ │ │ │ ├── SettingFragment.java
│ │ │ │ │ ├── LittleSisterFragment.java
│ │ │ │ │ └── GankMZFragment.java
│ │ │ │ ├── activity
│ │ │ │ │ ├── SplashActivity.java
│ │ │ │ │ ├── PictureDetailActivity.java
│ │ │ │ │ ├── AboutActivity.java
│ │ │ │ │ ├── SettingActivity.java
│ │ │ │ │ └── MainActivity.java
│ │ │ │ └── adapter
│ │ │ │ │ └── GankMZAdapter.java
│ │ │ │ ├── data
│ │ │ │ ├── result
│ │ │ │ │ └── GankResult.java
│ │ │ │ └── dto
│ │ │ │ │ └── GankMeizi.java
│ │ │ │ ├── widget
│ │ │ │ ├── RatioImageView.java
│ │ │ │ └── GlideRoundTransform.java
│ │ │ │ ├── DryInit.java
│ │ │ │ └── net
│ │ │ │ └── APIService.java
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── coderpig
│ │ │ └── com
│ │ │ └── drysisters
│ │ │ └── ExampleUnitTest.java
│ └── androidTest
│ │ └── java
│ │ └── coderpig
│ │ └── com
│ │ └── drysisters
│ │ └── ApplicationTest.java
├── build.gradle
└── proguard-rules.pro
├── settings.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── .gitignore
├── gradle.properties
├── README.md
├── config
└── dependencies.gradle
├── gradlew.bat
├── gradlew
└── LICENSE
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/app/my.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coder-pig/DrySister/HEAD/app/my.jks
--------------------------------------------------------------------------------
/app/src/main/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coder-pig/DrySister/HEAD/app/src/main/ic_launcher-web.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coder-pig/DrySister/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coder-pig/DrySister/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coder-pig/DrySister/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_nav_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coder-pig/DrySister/HEAD/app/src/main/res/mipmap-xhdpi/ic_nav_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coder-pig/DrySister/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/coder-pig/DrySister/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jun 05 19:27:09 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 | 240dp
6 | 0dp
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_bg_about_text_green.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_bg_about_text_purple.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shape_bg_about_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/test/java/coderpig/com/drysisters/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package coderpig.com.drysisters;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/utils/ResUtils.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.utils;
2 |
3 | import com.coderpig.drysisters.DrySisterApp;
4 |
5 | /**
6 | * 描述:获取文件资源工具类
7 | *
8 | * @author CoderPig on 2018/02/14 11:07.
9 | */
10 |
11 | public class ResUtils {
12 | /* 获取文件资源 */
13 | public static String getString(int strId) {
14 | return DrySisterApp.getContext().getResources().getString(strId);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/coderpig/com/drysisters/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package coderpig.com.drysisters;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/anim_fab_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/DryConstant.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters;
2 |
3 | /**
4 | * 描述:相关常量
5 | *
6 | * @author CoderPig on 2018/02/13 16:22.
7 | */
8 |
9 | public class DryConstant {
10 | public final static String FG_LITTLE_SISTER = "FG_LITTLE_SISTER";
11 | public final static String FG_NEWS = "FG_NEWS";
12 | public final static String FG_WEATHER = "FG_WEATHER";
13 | public final static String FG_SUBWAY = "FG_SUBWAY";
14 | public final static String FG_TOOLS = "FG_TOOLS";
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 | #5A78EA
5 | #FF4081
6 | #FFFFFF
7 | #000000
8 | #474747
9 | #E5E5E5
10 | #EEEEEE
11 | #C89EC4
12 | #67D5B5
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/DrySisterApp.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters;
2 |
3 | import android.app.Application;
4 |
5 | /**
6 | * 描述:Application类
7 | *
8 | * @author coder-pig: 2016/08/07 15:07
9 | */
10 | public class DrySisterApp extends Application {
11 |
12 | private static DrySisterApp context;
13 |
14 | @Override
15 | public void onCreate() {
16 | super.onCreate();
17 | context = this;
18 | DryInit.initTimber();
19 | DryInit.initOKHttp(this);
20 | }
21 |
22 | public static DrySisterApp getContext() {
23 | return context;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 |
4 | # generated files
5 | bin/
6 | gen/
7 | out/
8 | build/
9 |
10 | # Local configuration file (sdk path, etc)
11 | local.properties
12 |
13 | # Eclipse project files
14 | .classpath
15 | .project
16 |
17 | # Windows thumbnail db
18 | .DS_Store
19 | Thumbs.db
20 |
21 | # Proguard folder generated by Eclipse
22 | proguard/
23 |
24 | # IDEA/Android Studio project files, because
25 | # the project can be imported from settings.gradle
26 | .idea
27 | *.iml
28 |
29 | # Old-style IDEA project files
30 | *.ipr
31 | *.iws
32 |
33 | # Gradle cache
34 | .gradle
35 |
36 | # Sandbox stuff
37 | _sandbox
38 |
39 | # Backup files
40 | *~
41 | *.bak
42 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/anim_fab_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
13 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_mz.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/utils/SizeUtils.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.utils;
2 |
3 | import android.content.Context;
4 |
5 | /**
6 | * 描述:尺寸转换工具类
7 | *
8 | * @author coder-pig: 2016/08/17 11:47
9 | */
10 | public class SizeUtils {
11 |
12 | /** dp转px */
13 | public static int dp2px(Context context, float dpValue) {
14 | final float scale = context.getResources().getDisplayMetrics().density;
15 | return (int) (dpValue * scale + 0.5f);
16 | }
17 | /** px转dp */
18 | public static int px2dp(Context context, float pxValue) {
19 | final float scale = context.getResources().getDisplayMetrics().density;
20 | return (int) (pxValue / scale + 0.5f);
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_news.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_tools.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_subway.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_weather.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/utils/ToastUtils.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.utils;
2 |
3 | import android.view.Gravity;
4 | import android.widget.Toast;
5 |
6 | import com.coderpig.drysisters.DrySisterApp;
7 |
8 | /**
9 | * 描述:Toast 工具类
10 | *
11 | * @author CoderPig on 2018/02/14 11:06.
12 | */
13 |
14 | public class ToastUtils {
15 | public static void shortToast(String msg) {
16 | Toast toast = Toast.makeText(DrySisterApp.getContext(),msg, Toast.LENGTH_SHORT);
17 | toast.setGravity(Gravity.BOTTOM, 0, 40);
18 | toast.show();
19 | }
20 |
21 | public static void longToast(String msg) {
22 | Toast toast = Toast.makeText(DrySisterApp.getContext(),msg, Toast.LENGTH_LONG);
23 | toast.setGravity(Gravity.BOTTOM, 0, 40);
24 | toast.show();
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/utils/NetworkUtils.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.utils;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 | import android.net.NetworkInfo;
6 |
7 | /**
8 | * 描述:网络相关工具类
9 | *
10 | * @author coder-pig: 2016/08/22 10:24
11 | */
12 | public class NetworkUtils {
13 | /** 获取网络信息 */
14 | private static NetworkInfo getActiveNetworkInfo(Context context) {
15 | ConnectivityManager cm = (ConnectivityManager) context
16 | .getSystemService(Context.CONNECTIVITY_SERVICE);
17 | return cm.getActiveNetworkInfo();
18 | }
19 |
20 | /** 判断网络是否可用 */
21 | public static boolean isAvailable(Context context) {
22 | NetworkInfo info = getActiveNetworkInfo(context);
23 | return info != null && info.isAvailable();
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_picture_detail.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
19 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/fragment/NewsFragment.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | import com.coderpig.drysisters.R;
11 |
12 | /**
13 | * 描述:看资讯的Fragment
14 | *
15 | * @author jay on 2018/1/12 12:19
16 | */
17 |
18 | public class NewsFragment extends Fragment {
19 |
20 | public static NewsFragment newInstance() {
21 | NewsFragment fragment = new NewsFragment();
22 | return fragment;
23 | }
24 |
25 | @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
26 | return inflater.inflate(R.layout.fragment_news, container,false);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/fragment/ToolsFragment.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | import com.coderpig.drysisters.R;
11 |
12 | /**
13 | * 描述:小工具的Fragment
14 | *
15 | * @author jay on 2018/1/12 12:19
16 | */
17 |
18 | public class ToolsFragment extends Fragment {
19 |
20 | public static ToolsFragment newInstance() {
21 | ToolsFragment fragment = new ToolsFragment();
22 | return fragment;
23 | }
24 |
25 | @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
26 | return inflater.inflate(R.layout.fragment_tools, container,false);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/fragment/SubwayFragment.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | import com.coderpig.drysisters.R;
11 |
12 | /**
13 | * 描述:看天气的Fragment
14 | *
15 | * @author jay on 2018/1/12 12:19
16 | */
17 |
18 | public class SubwayFragment extends Fragment {
19 |
20 | public static SubwayFragment newInstance() {
21 | SubwayFragment fragment = new SubwayFragment();
22 | return fragment;
23 | }
24 |
25 | @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
26 | return inflater.inflate(R.layout.fragment_subway, container,false);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/fragment/WeatherFragment.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 |
10 | import com.coderpig.drysisters.R;
11 |
12 | /**
13 | * 描述:看天气的Fragment
14 | *
15 | * @author jay on 2018/1/12 12:19
16 | */
17 |
18 | public class WeatherFragment extends Fragment {
19 |
20 | public static WeatherFragment newInstance() {
21 | WeatherFragment fragment = new WeatherFragment();
22 | return fragment;
23 | }
24 |
25 | @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
26 | return inflater.inflate(R.layout.fragment_weather, container,false);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_bar_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/activity/SplashActivity.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.activity;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.annotation.Nullable;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.widget.TextView;
8 |
9 | import com.coderpig.drysisters.R;
10 |
11 | /**
12 | * 描述:闪屏页
13 | *
14 | * @author CoderPig on 2018/02/13 15:23.
15 | */
16 |
17 | public class SplashActivity extends AppCompatActivity{
18 | @Override
19 | protected void onCreate(@Nullable Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | setContentView(R.layout.activity_splash);
22 | TextView tv_logo = findViewById(R.id.tv_logo);
23 | tv_logo.postDelayed(this::jump,500L);
24 |
25 | }
26 |
27 | /* 完成一些初始化操作 */
28 | private void init() {
29 |
30 | }
31 |
32 | /* 页面逻辑跳转 */
33 | private void jump() {
34 | startActivity(new Intent(this, MainActivity.class));
35 | finish();
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/data/result/GankResult.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.data.result;
2 |
3 | import com.coderpig.drysisters.data.dto.GankMeizi;
4 |
5 | import java.util.ArrayList;
6 |
7 | /**
8 | * 描述:Gank.io返回的结果集
9 | *
10 | * @author CoderPig on 2018/02/14 10:52.
11 | */
12 |
13 | public class GankResult {
14 | private Boolean error;
15 | private ArrayList results;
16 |
17 | public GankResult() { }
18 |
19 | public GankResult(Boolean error, ArrayList results) {
20 | this.error = error;
21 | this.results = results;
22 | }
23 |
24 | public Boolean getError() {
25 | return error;
26 | }
27 |
28 | public void setError(Boolean error) {
29 | this.error = error;
30 | }
31 |
32 | public ArrayList getResults() {
33 | return results;
34 | }
35 |
36 | public void setResults(ArrayList results) {
37 | this.results = results;
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return "GankResult{" +
43 | "error=" + error +
44 | ", results=" + results.toString() +
45 | '}';
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/activity/PictureDetailActivity.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.activity;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.widget.ImageView;
7 |
8 | import com.bumptech.glide.Glide;
9 | import com.coderpig.drysisters.R;
10 | import com.r0adkll.slidr.Slidr;
11 |
12 | /**
13 | * 描述:图片详情页
14 | *
15 | * @author CoderPig on 2018/02/28 10:39.
16 | */
17 |
18 | public class PictureDetailActivity extends AppCompatActivity{
19 |
20 | private ImageView img_picture;
21 | private String picUrl;
22 |
23 | @Override
24 | protected void onCreate(@Nullable Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_picture_detail);
27 | Slidr.attach(this);
28 | initData();
29 | initView();
30 | }
31 |
32 | private void initData() {
33 | picUrl = getIntent().getStringExtra("pic_url");
34 | }
35 |
36 | private void initView() {
37 | img_picture = findViewById(R.id.img_picture);
38 | if(picUrl != null) {
39 | Glide.with(this).load(picUrl).into(img_picture);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/utils/PackageUtils.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.utils;
2 |
3 | import android.content.pm.PackageInfo;
4 | import android.content.pm.PackageManager;
5 |
6 | import com.coderpig.drysisters.DrySisterApp;
7 |
8 | /**
9 | * 描述:应用包相关的工具类
10 | *
11 | * @author CoderPig on 2018/02/28 18:01.
12 | */
13 |
14 | public class PackageUtils {
15 |
16 | public static int packageCode() {
17 | PackageManager manager = DrySisterApp.getContext().getPackageManager();
18 | int code = 0;
19 | try {
20 | PackageInfo info = manager.getPackageInfo(DrySisterApp.getContext().getPackageName(), 0);
21 | code = info.versionCode;
22 | } catch (PackageManager.NameNotFoundException e) {
23 | e.printStackTrace();
24 | }
25 | return code;
26 | }
27 |
28 | public static String packageName() {
29 | PackageManager manager = DrySisterApp.getContext().getPackageManager();
30 | String name = null;
31 | try {
32 | PackageInfo info = manager.getPackageInfo(DrySisterApp.getContext().getPackageName(), 0);
33 | name = info.versionName;
34 | } catch (PackageManager.NameNotFoundException e) {
35 | e.printStackTrace();
36 | }
37 | return name;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/activity/AboutActivity.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.activity;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.support.v7.widget.Toolbar;
7 |
8 | import com.coderpig.drysisters.R;
9 | import com.coderpig.drysisters.ui.fragment.AboutFragment;
10 | import com.r0adkll.slidr.Slidr;
11 |
12 | /**
13 | * 描述:关于的Activity
14 | *
15 | * @author jay on 2018/1/12 14:01
16 | */
17 |
18 | public class AboutActivity extends AppCompatActivity{
19 |
20 | private Toolbar toolbar;
21 |
22 | @Override
23 | protected void onCreate(@Nullable Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 | setContentView(R.layout.activity_about);
26 | Slidr.attach(this);
27 | initData();
28 | initView();
29 | }
30 |
31 | private void initData() {
32 |
33 | }
34 |
35 | private void initView() {
36 | toolbar = findViewById(R.id.toolbar);
37 | toolbar.setTitle("关于");
38 | setSupportActionBar(toolbar);
39 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
40 | toolbar.setNavigationOnClickListener(view -> finish());
41 |
42 | getSupportFragmentManager().beginTransaction().replace(R.id.cly_root, AboutFragment.newInstance()).commit();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/widget/RatioImageView.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 |
6 | /**
7 | * 描述:根据宽度自适应的ImageView
8 | *
9 | * @author CoderPig on 2018/02/14 16:25.
10 | */
11 |
12 | public class RatioImageView extends android.support.v7.widget.AppCompatImageView{
13 | private int originalWidth;
14 | private int originalHeight;
15 |
16 |
17 | public RatioImageView(Context context) {
18 | super(context);
19 | }
20 |
21 |
22 | public RatioImageView(Context context, AttributeSet attrs) {
23 | super(context, attrs);
24 | }
25 |
26 |
27 | public RatioImageView(Context context, AttributeSet attrs, int defStyleAttr) {
28 | super(context, attrs, defStyleAttr);
29 | }
30 |
31 |
32 | public void setOriginalSize(int originalWidth, int originalHeight) {
33 | this.originalWidth = originalWidth;
34 | this.originalHeight = originalHeight;
35 | }
36 |
37 |
38 | @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
39 | if (originalWidth > 0 && originalHeight > 0) {
40 | int width = MeasureSpec.getSize(widthMeasureSpec);
41 | setMeasuredDimension(width, width);
42 | } else {
43 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/activity/SettingActivity.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.activity;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.support.v7.widget.Toolbar;
7 |
8 | import com.coderpig.drysisters.R;
9 | import com.coderpig.drysisters.ui.fragment.SettingFragment;
10 | import com.r0adkll.slidr.Slidr;
11 |
12 | /**
13 | * 描述:设置的Activity
14 | *
15 | * @author jay on 2018/1/12 14:01
16 | */
17 |
18 | public class SettingActivity extends AppCompatActivity{
19 |
20 | private Toolbar toolbar;
21 |
22 | @Override
23 | protected void onCreate(@Nullable Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 | setContentView(R.layout.activity_setting);
26 | Slidr.attach(this);
27 | initData();
28 | initView();
29 | }
30 |
31 | private void initData() {
32 |
33 | }
34 |
35 | private void initView() {
36 | toolbar = findViewById(R.id.toolbar);
37 | toolbar.setTitle("设置");
38 | setSupportActionBar(toolbar);
39 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
40 | toolbar.setNavigationOnClickListener(view -> finish());
41 |
42 | getSupportFragmentManager().beginTransaction().replace(R.id.cly_root, SettingFragment.newInstance()).commit();
43 |
44 | }
45 |
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/DryInit.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters;
2 |
3 | import android.app.Application;
4 |
5 | import java.util.concurrent.TimeUnit;
6 |
7 | import okhttp3.OkHttpClient;
8 | import okhttp3.logging.HttpLoggingInterceptor;
9 | import timber.log.Timber;
10 |
11 | /**
12 | * 描述:完成一些基本构造
13 | *
14 | * @author CoderPig on 2018/02/14 10:36.
15 | */
16 |
17 | public class DryInit {
18 | private static Long HTTP_CONNECT_TIMEOUT = 30L;
19 | private static Long HTTP_WRITE_TIMEOUT = 30L;
20 | private static Long HTTP_READ_TIMEOUT = 30L;
21 |
22 | public static OkHttpClient mOkHttpClient;
23 |
24 | /* 初始化OkHttpClient */
25 | static void initOKHttp(Application app) {
26 | HttpLoggingInterceptor logging = new HttpLoggingInterceptor(message -> Timber.tag("OkHttps").d(message));
27 | logging.setLevel(HttpLoggingInterceptor.Level.BODY);
28 | OkHttpClient.Builder builder = new OkHttpClient.Builder()
29 | .connectTimeout(HTTP_CONNECT_TIMEOUT, TimeUnit.SECONDS)
30 | .writeTimeout(HTTP_WRITE_TIMEOUT, TimeUnit.SECONDS)
31 | .readTimeout(HTTP_READ_TIMEOUT, TimeUnit.SECONDS)
32 | .addInterceptor(logging);
33 | mOkHttpClient = builder.build();
34 | }
35 |
36 | /* 初始化Timber */
37 | static void initTimber() {
38 | if (BuildConfig.DEBUG) {
39 | Timber.plant(new Timber.DebugTree());
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DrySister更新记录
2 |
3 |
4 | ----------
5 |
6 | ## 版本:1.0.2
7 |
8 | >
9 | - 1.重新设计应用的UI,依旧是Material Design 风格,配色改为了蕾姆蓝,灰白;
10 | 界面更加简洁精致,把侧滑菜单的菜单替换了一组很萌的图表集;
11 | - 2.界面支持右滑关闭
12 | - 3.新增设置与关于页面
13 |
14 | **界面效果图**:
15 |
16 | ![][1]
17 |
18 | ![][2]
19 |
20 | ----------
21 |
22 |
23 | ## 版本:1.0.1
24 |
25 | >
26 | - 1.新版Material Design主界面搭建:[编码记录](http://blog.csdn.net/coder_pig/article/details/78988143) —— 2018.1.6
27 |
28 | **界面效果图**
29 |
30 | 
31 |
32 | ---
33 |
34 | ## 版本:1.0.0
35 |
36 |
37 |
38 | >
39 | - 1.完成项目搭建,托管Github,添加分支管理:[编码记录](http://blog.csdn.net/coder_pig/article/details/52135399) —— 2016.8.5
40 | - 2.把图片数据来源改成解析后台数据,使用自带抠脚Json解析:[编码记录](http://blog.csdn.net/coder_pig/article/details/52143980) —— 2016.8.7
41 | - 3.优化图片加载,编写图片异步加载框架SisterLoader:[编码记录](http://blog.csdn.net/coder_pig/article/details/52235436) —— 2016.8.18
42 | - 4.添加数据缓存,使用SQLite存储后台返回的数据:[编码记录](http://blog.csdn.net/coder_pig/article/details/52278625) —— 2016.8.22
43 | - 5.代码回顾,切换到AS3.0上代码调整,编写日志工具类:[编码记录](http://blog.csdn.net/coder_pig/article/details/78855294) —— 2017.12.20
44 | - 6.图标制作,代码混淆,签名打包,APK瘦身,应用发布: [编码记录](http://blog.csdn.net/coder_pig/article/details/78868926) —— 2017.12.21
45 |
46 | **界面效果图**
47 |
48 | 
49 |
50 |
51 | ----------
52 |
53 |
54 | [1]: http://static.zybuluo.com/coder-pig/us0jtehvornlgambkii7eaor/1.png
55 | [2]: http://static.zybuluo.com/coder-pig/gy11wi6ywre783a4wmlj9aac/2.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
22 |
23 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
23 |
24 |
25 |
26 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_setting.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
23 |
24 |
25 |
26 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_mz_content.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
18 |
19 |
20 |
21 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/net/APIService.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.net;
2 |
3 | import com.coderpig.drysisters.DryInit;
4 | import com.coderpig.drysisters.data.result.GankResult;
5 |
6 | import io.reactivex.Flowable;
7 | import retrofit2.Retrofit;
8 | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
9 | import retrofit2.converter.gson.GsonConverterFactory;
10 | import retrofit2.http.GET;
11 | import retrofit2.http.Path;
12 |
13 | /**
14 | * 描述:API 请求接口
15 | *
16 | * @author CoderPig on 2018/02/14 10:40.
17 | */
18 |
19 | public class APIService {
20 |
21 | private static String BASE_URL = "http://www.coderpig.com/"; //未启用
22 |
23 | public APIs apis;
24 |
25 | private static APIService instance;
26 |
27 | public static APIService getInstance() {
28 | if (instance == null) {
29 | instance = new APIService();
30 | }
31 | return instance;
32 | }
33 |
34 | private APIService() {
35 | Retrofit storeRestAPI = new Retrofit.Builder().baseUrl(BASE_URL)
36 | .client(DryInit.mOkHttpClient)
37 | .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
38 | .addConverterFactory(GsonConverterFactory.create())
39 | .build();
40 | apis = storeRestAPI.create(APIs.class);
41 | }
42 |
43 | public interface APIs{
44 |
45 | /* Gank.io 妹子图 */
46 | @GET("http://gank.io/api/data/福利/{count}/{page}")
47 | Flowable fetchGankMZ(
48 | @Path("count") int count,
49 | @Path("page") int page
50 | );
51 |
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/utils/RxSchedulers.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.utils;
2 |
3 | import com.coderpig.drysisters.R;
4 | import com.google.gson.JsonSyntaxException;
5 |
6 | import java.net.ConnectException;
7 | import java.net.SocketException;
8 | import java.net.SocketTimeoutException;
9 | import java.net.UnknownHostException;
10 |
11 | import io.reactivex.ObservableTransformer;
12 | import io.reactivex.android.schedulers.AndroidSchedulers;
13 | import io.reactivex.schedulers.Schedulers;
14 | import timber.log.Timber;
15 |
16 | /**
17 | * 描述:Rx 处理工具类
18 | *
19 | * @author CoderPig on 2018/02/14 11:06.
20 | */
21 |
22 | public class RxSchedulers {
23 | public static ObservableTransformer compose() {
24 | return upstream ->
25 | upstream.subscribeOn(Schedulers.io())
26 | .observeOn(AndroidSchedulers.mainThread());
27 | }
28 |
29 | public static void processRequestException(Throwable e) {
30 | if(e instanceof ConnectException || e instanceof SocketException) {
31 | ToastUtils.shortToast(ResUtils.getString(R.string.network_connected_exception));
32 | } else if(e instanceof SocketTimeoutException) {
33 | ToastUtils.shortToast(ResUtils.getString(R.string.network_socket_time_out));
34 | } else if(e instanceof JsonSyntaxException) {
35 | ToastUtils.shortToast(ResUtils.getString(R.string.network_json_syntax_exception));
36 | } else if(e instanceof UnknownHostException) {
37 | ToastUtils.shortToast(ResUtils.getString(R.string.network_unknown_host));
38 | } else {
39 | Timber.d(e.getMessage());
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/fragment/AboutFragment.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.TextView;
11 |
12 | import com.coderpig.drysisters.R;
13 | import com.coderpig.drysisters.utils.PackageUtils;
14 | import com.coderpig.drysisters.utils.ResUtils;
15 |
16 | /**
17 | * 描述: 关于的Fragment
18 | *
19 | * @author CoderPig on 2018/02/28 14:33.
20 | */
21 |
22 | public class AboutFragment extends Fragment {
23 |
24 | private TextView tv_app_version;
25 |
26 | public static AboutFragment newInstance() {
27 | AboutFragment fragment = new AboutFragment();
28 | return fragment;
29 | }
30 |
31 | @Nullable
32 | @Override
33 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
34 | View view = inflater.inflate(R.layout.fragment_about, container, false);
35 | tv_app_version = view.findViewById(R.id.tv_app_version);
36 | return view;
37 | }
38 |
39 | @Override
40 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
41 | super.onViewCreated(view, savedInstanceState);
42 | String version = PackageUtils.packageName();
43 | if(version != null) {
44 | String msg = String.format(ResUtils.getString(R.string.app_version), version);
45 | tv_app_version.setText(msg);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/fragment/SettingFragment.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.v4.app.Fragment;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.TextView;
11 |
12 | import com.coderpig.drysisters.R;
13 | import com.coderpig.drysisters.utils.PackageUtils;
14 | import com.coderpig.drysisters.utils.ResUtils;
15 |
16 | /**
17 | * 描述: 应用设置的Fragment
18 | *
19 | * @author CoderPig on 2018/02/28 13:56.
20 | */
21 |
22 | public class SettingFragment extends Fragment {
23 |
24 | private TextView tv_app_version;
25 |
26 | public static SettingFragment newInstance() {
27 | SettingFragment fragment = new SettingFragment();
28 | return fragment;
29 | }
30 |
31 | @Nullable
32 | @Override
33 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
34 | View view = inflater.inflate(R.layout.fragment_setting, container, false);
35 | tv_app_version = view.findViewById(R.id.tv_app_version);
36 | return view;
37 | }
38 |
39 | @Override
40 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
41 | super.onViewCreated(view, savedInstanceState);
42 | String version = PackageUtils.packageName();
43 | if(version != null) {
44 | String msg = String.format(ResUtils.getString(R.string.cur_version), version);
45 | tv_app_version.setText(msg);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_weather.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
17 |
18 |
22 |
23 |
27 |
28 |
29 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
19 |
20 |
28 |
29 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/data/dto/GankMeizi.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.data.dto;
2 |
3 | /**
4 | * 描述:Gank.io 返回的妹子
5 | *
6 | * @author CoderPig on 2018/02/14 10:53.
7 | */
8 |
9 | public class GankMeizi {
10 | private String _id;
11 | private String createdAt;
12 | private String desc;
13 | private String publishedAt;
14 | private String source;
15 | private String url;
16 | private Boolean used;
17 | private String who;
18 |
19 | public String get_id() {
20 | return _id;
21 | }
22 |
23 | public void set_id(String _id) {
24 | this._id = _id;
25 | }
26 |
27 | public String getCreatedAt() {
28 | return createdAt;
29 | }
30 |
31 | public void setCreatedAt(String createdAt) {
32 | this.createdAt = createdAt;
33 | }
34 |
35 | public String getDesc() {
36 | return desc;
37 | }
38 |
39 | public void setDesc(String desc) {
40 | this.desc = desc;
41 | }
42 |
43 | public String getPublishedAt() {
44 | return publishedAt;
45 | }
46 |
47 | public void setPublishedAt(String publishedAt) {
48 | this.publishedAt = publishedAt;
49 | }
50 |
51 | public String getSource() {
52 | return source;
53 | }
54 |
55 | public void setSource(String source) {
56 | this.source = source;
57 | }
58 |
59 | public Boolean getUsed() {
60 | return used;
61 | }
62 |
63 | public void setUsed(Boolean used) {
64 | this.used = used;
65 | }
66 |
67 | public String getWho() {
68 | return who;
69 | }
70 |
71 | public void setWho(String who) {
72 | this.who = who;
73 | }
74 |
75 | public String getUrl() {
76 | return url;
77 | }
78 |
79 | public void setUrl(String url) {
80 | this.url = url;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_tools.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_about.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_fab_love.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_news.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_sister.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_little_sister.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
23 |
24 |
32 |
33 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
18 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
34 |
35 |
39 |
40 |
44 |
45 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/config/dependencies.gradle:
--------------------------------------------------------------------------------
1 | def junitVersion = "4.12"
2 | def supportVersion = "27.0.2"
3 | def constraintVersion = "1.0.2"
4 | def phoneViewVersion = "2.1.3"
5 | def slidrVersion = "2.0.6"
6 | def roundImageViewVersion = "2.3.0"
7 | def rxJavaVersion = "2.1.9"
8 | def rxAndroidVersion = "2.0.1"
9 | def okhttpVersion = "3.9.1"
10 | def retrofitVersion = "2.3.0"
11 | def glideVersion = "4.6.1"
12 | def timberViersion = "4.6.1"
13 |
14 |
15 | project.ext {
16 | depend_android = [
17 | compileSdkVersion: 28,
18 | minSdkVersion : 21,
19 | targetSdkVersion : 28,
20 | ]
21 |
22 | depend_lib = [
23 | "junit" : "junit:junit:${junitVersion}",
24 | "appcompat-v7" : "com.android.support:appcompat-v7:${supportVersion}",
25 | "design" : "com.android.support:design:${supportVersion}",
26 | "cardview" : "com.android.support:cardview-v7:${supportVersion}",
27 | "constraint-layout" : "com.android.support.constraint:constraint-layout:${constraintVersion}",
28 | "phoneView" : "com.github.chrisbanes:PhotoView:${phoneViewVersion}",
29 | "slidr" : "com.r0adkll:slidableactivity:${slidrVersion}",
30 | "roundedimageview" : "com.makeramen:roundedimageview:${roundImageViewVersion}",
31 |
32 | "rxjava" : "io.reactivex.rxjava2:rxjava:${rxJavaVersion}",
33 | "rxandroid" : "io.reactivex.rxjava2:rxandroid:${rxAndroidVersion}",
34 |
35 | "okhttp" : "com.squareup.okhttp3:okhttp:${okhttpVersion}",
36 | "okhttp-interceptor": "com.squareup.okhttp3:logging-interceptor:${okhttpVersion}",
37 | "retrofit" : "com.squareup.retrofit2:retrofit:${retrofitVersion}",
38 | "converter-gson" : "com.squareup.retrofit2:converter-gson:${retrofitVersion}",
39 | "rxjava2-adapter" : "com.squareup.retrofit2:adapter-rxjava2:${retrofitVersion}",
40 | "glide" : "com.github.bumptech.glide:glide:${glideVersion}",
41 | "glide-compiler" : "com.github.bumptech.glide:compiler:${glideVersion}",
42 |
43 | "timber" : "com.jakewharton.timber:timber:${timberViersion}"
44 |
45 | ]
46 | }
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | def depend_android = rootProject.ext.depend_android
4 | def depend_lib = rootProject.ext.depend_lib
5 |
6 |
7 | android {
8 | signingConfigs {
9 | release {
10 | storeFile file('my.jks')
11 | storePassword '123456'
12 | keyAlias 'DrySister'
13 | keyPassword '654321'
14 | }
15 | }
16 | compileSdkVersion depend_android["compileSdkVersion"]
17 | defaultConfig {
18 | applicationId "com.coderpig.drysisters"
19 | minSdkVersion depend_android["minSdkVersion"]
20 | targetSdkVersion depend_android["targetSdkVersion"]
21 | versionCode 3
22 | versionName "1.0.2"
23 | }
24 | buildTypes {
25 | debug {
26 | minifyEnabled false
27 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
28 | }
29 | release {
30 | signingConfig signingConfigs.release
31 | // minifyEnabled true
32 | // shrinkResources true
33 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
34 | }
35 | }
36 | compileOptions {
37 | targetCompatibility 1.8
38 | sourceCompatibility 1.8
39 | }
40 | }
41 |
42 | dependencies {
43 | implementation fileTree(include: ['*.jar'], dir: 'libs')
44 | testImplementation depend_lib["junit"]
45 | implementation depend_lib["appcompat-v7"]
46 | implementation depend_lib["design"]
47 | implementation depend_lib["cardview"]
48 | implementation depend_lib["constraint-layout"]
49 | implementation depend_lib["phoneView"]
50 | implementation depend_lib["slidr"]
51 | implementation depend_lib["roundedimageview"]
52 | implementation depend_lib["rxjava"]
53 | implementation depend_lib["rxandroid"]
54 | implementation depend_lib["okhttp"]
55 | implementation depend_lib["okhttp-interceptor"]
56 | implementation depend_lib["retrofit"]
57 | implementation depend_lib["converter-gson"]
58 | implementation depend_lib["rxjava2-adapter"]
59 | implementation depend_lib["glide"]
60 | annotationProcessor depend_lib["glide-compiler"]
61 | implementation depend_lib["timber"]
62 |
63 | }
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\Software\Coding\android-sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | -dontnote android.net.http.*
13 | -dontnote org.apache.commons.codec.**
14 | -dontnote org.apache.http.**
15 |
16 | #指定压缩级别
17 | -optimizationpasses 5
18 |
19 | #不跳过非公共的库的类成员
20 | -dontskipnonpubliclibraryclassmembers
21 |
22 | #混淆时采用的算法
23 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
24 |
25 | #把混淆类中的方法名也混淆了
26 | -useuniqueclassmembernames
27 |
28 | #优化时允许访问并修改有修饰符的类和类的成员
29 | -allowaccessmodification
30 |
31 | #将文件来源重命名为“SourceFile”字符串
32 | -renamesourcefileattribute SourceFile
33 | #保留行号
34 | -keepattributes SourceFile,LineNumberTable
35 | #保持泛型
36 | -keepattributes Signature
37 |
38 | #保持所有实现 Serializable 接口的类成员
39 | -keepclassmembers class * implements java.io.Serializable {
40 | static final long serialVersionUID;
41 | private static final java.io.ObjectStreamField[] serialPersistentFields;
42 | private void writeObject(java.io.ObjectOutputStream);
43 | private void readObject(java.io.ObjectInputStream);
44 | java.lang.Object writeReplace();
45 | java.lang.Object readResolve();
46 | }
47 |
48 | #Fragment不需要在AndroidManifest.xml中注册,需要额外保护下
49 | -keep public class * extends android.support.v4.app.Fragment
50 | -keep public class * extends android.app.Fragment
51 |
52 | # 保持测试相关的代码
53 | -dontnote junit.framework.**
54 | -dontnote junit.runner.**
55 | -dontwarn android.test.**
56 | -dontwarn android.support.test.**
57 | -dontwarn org.junit.**
58 |
59 |
60 | # Okhttp3 混淆
61 | -dontwarn okhttp3.**
62 | -dontwarn okio.**
63 | -dontwarn javax.annotation.**
64 |
65 |
66 |
67 | # Glide混淆
68 | -keep public class * implements com.bumptech.glide.module.GlideModule
69 | -keep public class * extends com.bumptech.glide.module.AppGlideModule
70 | -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
71 | **[] $VALUES;
72 | public *;
73 | }
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_subway.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/widget/GlideRoundTransform.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.widget;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.graphics.Bitmap;
6 | import android.graphics.BitmapShader;
7 | import android.graphics.Canvas;
8 | import android.graphics.Paint;
9 | import android.graphics.RectF;
10 |
11 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
12 | import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
13 | import com.bumptech.glide.load.resource.bitmap.TransformationUtils;
14 |
15 | import java.security.MessageDigest;
16 |
17 | /**
18 | * 描述:
19 | *
20 | * @author CoderPig on 2018/02/14 16:50.
21 | */
22 |
23 | public class GlideRoundTransform extends BitmapTransformation {
24 |
25 | private static float radius = 0f;
26 |
27 | public GlideRoundTransform(Context context) {
28 | this(context, 4);
29 | }
30 |
31 | public GlideRoundTransform(Context context, int dp) {
32 | super(context);
33 | this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
34 | }
35 |
36 | @Override
37 | protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
38 | Bitmap bitmap = TransformationUtils.centerCrop(pool, toTransform, outWidth, outHeight);
39 | return roundCrop(pool, bitmap);
40 | }
41 |
42 | private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {
43 | if (source == null) return null;
44 |
45 | Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
46 | if (result == null) {
47 | result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
48 | }
49 |
50 | Canvas canvas = new Canvas(result);
51 | Paint paint = new Paint();
52 | paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
53 | paint.setAntiAlias(true);
54 | RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
55 | canvas.drawRoundRect(rectF, radius, radius, paint);
56 | return result;
57 | }
58 |
59 | public String getId() {
60 | return getClass().getName() + Math.round(radius);
61 | }
62 |
63 | @Override
64 | public void updateDiskCacheKey(MessageDigest messageDigest) {
65 |
66 | }
67 |
68 | }
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/adapter/GankMZAdapter.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.adapter;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.ImageView;
10 |
11 | import com.bumptech.glide.Glide;
12 | import com.bumptech.glide.request.RequestOptions;
13 | import com.coderpig.drysisters.R;
14 | import com.coderpig.drysisters.data.dto.GankMeizi;
15 | import com.coderpig.drysisters.ui.activity.PictureDetailActivity;
16 |
17 | import java.util.ArrayList;
18 |
19 | /**
20 | * 描述:
21 | *
22 | * @author CoderPig on 2018/02/14 12:15.
23 | */
24 |
25 | public class GankMZAdapter extends RecyclerView.Adapter {
26 |
27 | private Context mContext;
28 | private ArrayList mzs = new ArrayList<>();
29 |
30 | public GankMZAdapter(Context mContext, ArrayList mzs) {
31 | this.mContext = mContext;
32 | this.mzs = mzs;
33 | }
34 |
35 | public void addAll(ArrayList data) {
36 | mzs.clear();
37 | mzs.addAll(data);
38 | notifyDataSetChanged();
39 | }
40 |
41 | public void loadMore(ArrayList data) {
42 | mzs.addAll(data);
43 | }
44 |
45 | @Override
46 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
47 | return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_mz, parent, false));
48 | }
49 |
50 | @Override
51 | public void onBindViewHolder(ViewHolder holder, int position) {
52 | holder.bind(mzs.get(position));
53 | }
54 |
55 | @Override
56 | public int getItemCount() {
57 | return mzs.size();
58 | }
59 |
60 | class ViewHolder extends RecyclerView.ViewHolder {
61 |
62 | ImageView img_content;
63 |
64 | ViewHolder(View itemView) {
65 | super(itemView);
66 | img_content = itemView.findViewById(R.id.img_content);
67 | }
68 |
69 | void bind(GankMeizi data) {
70 | Glide.with(mContext)
71 | .load(data.getUrl())
72 | .apply(new RequestOptions()
73 | .centerCrop())
74 | .into(img_content);
75 | img_content.setOnClickListener(view -> {
76 | Intent intent = new Intent(mContext, PictureDetailActivity.class);
77 | intent.putExtra("pic_url", data.getUrl());
78 | mContext.startActivity(intent);
79 | });
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_menu_setting.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/fragment/LittleSisterFragment.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.fragment;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.annotation.NonNull;
6 | import android.support.annotation.Nullable;
7 | import android.support.design.widget.TabLayout;
8 | import android.support.v4.app.Fragment;
9 | import android.support.v4.app.FragmentManager;
10 | import android.support.v4.app.FragmentPagerAdapter;
11 | import android.support.v4.view.ViewPager;
12 | import android.view.LayoutInflater;
13 | import android.view.View;
14 | import android.view.ViewGroup;
15 |
16 | import com.coderpig.drysisters.R;
17 |
18 | import io.reactivex.disposables.CompositeDisposable;
19 |
20 |
21 | /**
22 | * 描述:妹看小姐姐的Fragment
23 | *
24 | * @author jay on 2018/1/12 12:19
25 | */
26 |
27 | public class LittleSisterFragment extends Fragment{
28 |
29 | private Context mContext;
30 | private TabLayout tl_little_sister;
31 | private ViewPager vp_content;
32 | protected CompositeDisposable mSubscriptions;
33 |
34 | public static LittleSisterFragment newInstance() {
35 | LittleSisterFragment fragment = new LittleSisterFragment();
36 | return fragment;
37 | }
38 |
39 | @Nullable @Override
40 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
41 | View view = inflater.inflate(R.layout.fragment_little_sister, container, false);
42 | tl_little_sister = view.findViewById(R.id.tl_little_sister);
43 | vp_content = view.findViewById(R.id.vp_content);
44 | return view;
45 | }
46 |
47 | @Override
48 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
49 | super.onViewCreated(view, savedInstanceState);
50 | mContext = getActivity();
51 | mSubscriptions = new CompositeDisposable();
52 | TabFragmentPagerAdapter adapter = new TabFragmentPagerAdapter(this.getChildFragmentManager());
53 | vp_content.setAdapter(adapter);
54 | tl_little_sister.setupWithViewPager(vp_content);
55 | }
56 |
57 | @Override public void onDestroy() {
58 | super.onDestroy();
59 | mSubscriptions.clear();
60 | }
61 |
62 | private class TabFragmentPagerAdapter extends FragmentPagerAdapter {
63 | private final String[] mTitles = {"Gank.io"};
64 |
65 | private TabFragmentPagerAdapter(FragmentManager fm) {
66 | super(fm);
67 | }
68 |
69 | @Override
70 | public Fragment getItem(int position) {
71 | return GankMZFragment.newInstance();
72 | }
73 |
74 | @Override
75 | public int getCount() {
76 | return mTitles.length;
77 | }
78 |
79 | @Override
80 | public CharSequence getPageTitle(int position) {
81 | return mTitles[position];
82 | }
83 | }
84 |
85 |
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | DrySisters
3 | Dry
4 | 下一个
5 | 上一个
6 | 抽屉打开
7 | 抽屉关闭
8 | 天天吃肉吃不胖,天天DrySister身体棒
9 |
10 |
11 | 看看
12 | 看小姐姐
13 | 读书看报
14 |
15 | 用用
16 | 查查天气
17 | 查查地铁
18 | 小工具箱
19 |
20 | 其他
21 | 设置
22 | 关于
23 | DrySister Version: %1$s
24 |
25 |
26 | 前方正在施工…
27 |
28 |
29 | 尚未连接网络,请打开网络重新加载!
30 | 网络连接异常,请稍后重试!
31 | 网络请求超时,请检查网络状态!
32 | 服务器数据异常,请稍候重试!
33 | 当前网络不可用,请检查网络情况!
34 |
35 |
36 | 刷新成功!
37 | 嘤嘤嘤,新增%1$d枚%2$s!
38 |
39 |
40 | 仅在WIFI下加载图片
41 | 清空缓存
42 | 当前缓存 %1$f mb
43 | 检查更新
44 | 当前版本 %1$s
45 | 给个好评
46 | 问题反馈
47 | 推荐给好基友
48 | 联系我
49 |
50 |
51 | Version %1$s
52 | 关于DrySister
53 |
54 | DrySister,直译干妹子,是小猪2016年写的Android基础入门教程附带的实战项目,
55 | 项目开源,遵循GPL v3协议,
56 | \n\n仓库地址:https://github.com/coder-pig/DrySister
57 | \n\n前期代码实现有详细的实现讲解,后面可能只说下遇到的问题以及难点。妹子源会慢慢增加,
58 | 除此之外还会添加一些新的小工具,敬请期待!项目仅用于技术交流学习,请勿用于商业用途!
59 | \n\n如果你在使用过程中有任何建议或者大胆的想法,
60 | \n欢迎加QQ群:518568422 进行反馈,
61 | \n或者在酷安评论区留言与小猪激烈摔♂跤;
62 | \n\n依次谢谢:
63 | \n\n 1.代码家提供的Gank.API
64 | \n 2.Drakeet的开源项目Meizhi
65 | \n 3.小荳的阿里健康品牌图标库的SVG图标,链接:
66 | \n http://iconfont.cn/collections/detail?cid=1312
67 | \n 很萌的一组图标,嘤嘤嘤!
68 |
69 | 关于我
70 |
71 | 一个三流Android开发者,会点Python,
72 | \n喜欢写有趣的文章,写过一套Android入门教程;
73 | \n博客:http://blog.csdn.net/coder_pig
74 | \nGitHub:https://github.com/coder-pig
75 | \n掘金和简书:太长不贴,自己搜coder-pig
76 |
77 | 用到的开源库(闲了再补充协议)
78 |
79 | com.android.support:appcompat-v7
80 | \ncom.android.support:design
81 | \ncom.android.support:cardview-v7
82 | \ncom.android.support.constraint:constraint-layout
83 | \ncom.github.chrisbanes:PhotoView
84 | \ncom.r0adkll:slidableactivity
85 | \ncom.makeramen:roundedimageview
86 | \nio.reactivex.rxjava2:rxjava
87 | \nio.reactivex.rxjava2:rxandroid
88 | \ncom.squareup.okhttp3:okhttp
89 | \ncom.squareup.okhttp3:logging-interceptor
90 | \ncom.squareup.retrofit2:retrofit
91 | \ncom.squareup.retrofit2:converter-gson
92 | \ncom.squareup.retrofit2:adapter-rxjava2
93 | \ncom.github.bumptech.glide:glide
94 | \ncom.github.bumptech.glide:compiler
95 | \ncom.jakewharton.timber:timber
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
10 |
12 |
14 |
16 |
18 |
20 |
22 |
24 |
26 |
28 |
30 |
32 |
34 |
36 |
38 |
40 |
42 |
44 |
46 |
48 |
50 |
52 |
54 |
56 |
58 |
60 |
62 |
64 |
66 |
68 |
70 |
72 |
74 |
75 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/activity/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.activity;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.annotation.NonNull;
6 | import android.support.constraint.ConstraintLayout;
7 | import android.support.design.widget.NavigationView;
8 | import android.support.v4.app.FragmentManager;
9 | import android.support.v4.view.GravityCompat;
10 | import android.support.v4.widget.DrawerLayout;
11 | import android.support.v7.app.ActionBarDrawerToggle;
12 | import android.support.v7.app.AppCompatActivity;
13 | import android.support.v7.widget.Toolbar;
14 | import android.view.MenuItem;
15 | import android.widget.TextView;
16 |
17 | import com.coderpig.drysisters.DryConstant;
18 | import com.coderpig.drysisters.R;
19 | import com.coderpig.drysisters.ui.fragment.LittleSisterFragment;
20 | import com.coderpig.drysisters.ui.fragment.NewsFragment;
21 | import com.coderpig.drysisters.ui.fragment.SubwayFragment;
22 | import com.coderpig.drysisters.ui.fragment.ToolsFragment;
23 | import com.coderpig.drysisters.ui.fragment.WeatherFragment;
24 | import com.coderpig.drysisters.utils.PackageUtils;
25 | import com.coderpig.drysisters.utils.ResUtils;
26 |
27 | public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
28 |
29 | private Toolbar toolbar;
30 | private DrawerLayout drawer_layout;
31 | private NavigationView nav_view;
32 | private TextView tv_nav_title;
33 | private ConstraintLayout cly_main_content;
34 | private FragmentManager mFgManager;
35 |
36 | @Override
37 | protected void onCreate(Bundle savedInstanceState) {
38 | super.onCreate(savedInstanceState);
39 | setContentView(R.layout.activity_main);
40 | mFgManager = getSupportFragmentManager();
41 | initView();
42 | initData();
43 | }
44 |
45 | private void initView() {
46 | toolbar = findViewById(R.id.toolbar);
47 | nav_view = findViewById(R.id.nav_view);
48 | tv_nav_title = nav_view.getHeaderView(0).findViewById(R.id.tv_nav_title);
49 | drawer_layout = findViewById(R.id.drawer_layout);
50 | cly_main_content = findViewById(R.id.cly_main_content);
51 |
52 | setSupportActionBar(toolbar);
53 | nav_view.setItemIconTintList(null);
54 | nav_view.setNavigationItemSelectedListener(this);
55 |
56 | ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
57 | this, drawer_layout, toolbar, R.string.drawer_open, R.string.drawer_close);
58 | drawer_layout.addDrawerListener(toggle);
59 | toggle.syncState();
60 | }
61 |
62 | private void initData() {
63 | mFgManager.beginTransaction().replace(R.id.cly_main_content,
64 | LittleSisterFragment.newInstance(), DryConstant.FG_LITTLE_SISTER).commit();
65 | toolbar.setTitle(ResUtils.getString(R.string.menu_see_little_sister));
66 | String version = PackageUtils.packageName();
67 | if(version != null) {
68 | String msg = String.format(ResUtils.getString(R.string.menu_drysister_version), version);
69 | tv_nav_title.setText(msg);
70 | }
71 | }
72 |
73 | @Override
74 | public boolean onNavigationItemSelected(@NonNull MenuItem item) {
75 | switch (item.getItemId()) {
76 | case R.id.nav_see_little_sister:
77 | if (mFgManager.findFragmentByTag(DryConstant.FG_LITTLE_SISTER) == null) {
78 | mFgManager.beginTransaction().replace(R.id.cly_main_content,
79 | LittleSisterFragment.newInstance(), DryConstant.FG_LITTLE_SISTER).commit();
80 | toolbar.setTitle(ResUtils.getString(R.string.menu_see_little_sister));
81 | }
82 | break;
83 | case R.id.nav_see_news:
84 | if (mFgManager.findFragmentByTag(DryConstant.FG_NEWS) == null) {
85 | mFgManager.beginTransaction().replace(R.id.cly_main_content,
86 | NewsFragment.newInstance(), DryConstant.FG_NEWS).commit();
87 | toolbar.setTitle(ResUtils.getString(R.string.menu_see_news));
88 | }
89 | break;
90 | case R.id.nav_use_check_weather:
91 | if (mFgManager.findFragmentByTag(DryConstant.FG_WEATHER) == null) {
92 | mFgManager.beginTransaction().replace(R.id.cly_main_content,
93 | WeatherFragment.newInstance(), DryConstant.FG_WEATHER).commit();
94 | toolbar.setTitle(ResUtils.getString(R.string.menu_use_check_weather));
95 | }
96 | break;
97 | case R.id.nav_use_check_subway:
98 | if (mFgManager.findFragmentByTag(DryConstant.FG_SUBWAY) == null) {
99 | mFgManager.beginTransaction().replace(R.id.cly_main_content,
100 | SubwayFragment.newInstance(), DryConstant.FG_SUBWAY).commit();
101 | toolbar.setTitle(ResUtils.getString(R.string.menu_use_check_subway));
102 | }
103 | break;
104 | case R.id.nav_use_tools:
105 | if (mFgManager.findFragmentByTag(DryConstant.FG_TOOLS) == null) {
106 | mFgManager.beginTransaction().replace(R.id.cly_main_content,
107 | ToolsFragment.newInstance(), DryConstant.FG_TOOLS).commit();
108 | toolbar.setTitle(ResUtils.getString(R.string.menu_use_tools));
109 | }
110 | break;
111 | case R.id.nav_else_setting:
112 | startActivity(new Intent(this, SettingActivity.class));
113 | break;
114 | case R.id.nav_else_about:
115 | startActivity(new Intent(this, AboutActivity.class));
116 | break;
117 | }
118 | drawer_layout.closeDrawer(GravityCompat.START);
119 | return true;
120 | }
121 |
122 | @Override
123 | public void onBackPressed() {
124 | if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
125 | drawer_layout.closeDrawer(GravityCompat.START);
126 | } else {
127 | super.onBackPressed();
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
13 |
14 |
23 |
24 |
34 |
35 |
44 |
45 |
56 |
57 |
58 |
73 |
74 |
85 |
86 |
101 |
102 |
113 |
114 |
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/app/src/main/java/com/coderpig/drysisters/ui/fragment/GankMZFragment.java:
--------------------------------------------------------------------------------
1 | package com.coderpig.drysisters.ui.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.NonNull;
5 | import android.support.annotation.Nullable;
6 | import android.support.design.widget.FloatingActionButton;
7 | import android.support.v4.app.Fragment;
8 | import android.support.v4.view.ViewCompat;
9 | import android.support.v4.view.ViewPropertyAnimatorListener;
10 | import android.support.v4.view.animation.FastOutSlowInInterpolator;
11 | import android.support.v4.widget.SwipeRefreshLayout;
12 | import android.support.v7.widget.GridLayoutManager;
13 | import android.support.v7.widget.LinearLayoutManager;
14 | import android.support.v7.widget.RecyclerView;
15 | import android.view.LayoutInflater;
16 | import android.view.View;
17 | import android.view.ViewGroup;
18 | import android.view.animation.Interpolator;
19 |
20 | import com.coderpig.drysisters.R;
21 | import com.coderpig.drysisters.data.dto.GankMeizi;
22 | import com.coderpig.drysisters.net.APIService;
23 | import com.coderpig.drysisters.ui.adapter.GankMZAdapter;
24 | import com.coderpig.drysisters.utils.ResUtils;
25 | import com.coderpig.drysisters.utils.RxSchedulers;
26 | import com.coderpig.drysisters.utils.ToastUtils;
27 |
28 | import java.util.ArrayList;
29 |
30 | import io.reactivex.android.schedulers.AndroidSchedulers;
31 | import io.reactivex.disposables.CompositeDisposable;
32 | import io.reactivex.disposables.Disposable;
33 | import io.reactivex.schedulers.Schedulers;
34 |
35 | /**
36 | * 描述:Gank.io妹子Fragment
37 | *
38 | * @author CoderPig on 2018/02/14 09:49.
39 | */
40 |
41 | public class GankMZFragment extends Fragment {
42 |
43 | private static final String TAG = "GankMZFragment";
44 | private SwipeRefreshLayout srl_refresh;
45 | private FloatingActionButton fab_top;
46 | private RecyclerView rec_mz;
47 | private CompositeDisposable mSubscriptions;
48 | private GankMZAdapter mAdapter;
49 | private static final int PRELOAD_SIZE = 6;
50 | private int mCurPage = 1;
51 | private ArrayList mData;
52 | private final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator();
53 |
54 | public static GankMZFragment newInstance() {
55 | return new GankMZFragment();
56 | }
57 |
58 |
59 | @Nullable
60 | @Override
61 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
62 | View view = inflater.inflate(R.layout.fragment_mz_content, container, false);
63 | srl_refresh = view.findViewById(R.id.srl_refresh);
64 | rec_mz = view.findViewById(R.id.rec_mz);
65 | fab_top = view.findViewById(R.id.fab_top);
66 | srl_refresh.setOnRefreshListener(() -> {
67 | mCurPage = 1;
68 | fetchGankMZ(true);
69 | });
70 | final GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 2);
71 | rec_mz.setLayoutManager(layoutManager);
72 | rec_mz.addOnScrollListener(new RecyclerView.OnScrollListener() {
73 | @Override
74 | public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
75 | super.onScrollStateChanged(recyclerView, newState);
76 | LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
77 | if (newState == RecyclerView.SCROLL_STATE_IDLE) {//加载更多
78 | if (layoutManager.getItemCount() - recyclerView.getChildCount() <= layoutManager.findFirstVisibleItemPosition()) {
79 | ++mCurPage;
80 | fetchGankMZ(false);
81 | }
82 | }
83 | if (layoutManager.findFirstVisibleItemPosition() != 0) {
84 | fabInAnim();
85 | } else {
86 | fabOutAnim();
87 | }
88 | }
89 | });
90 | fab_top.setOnClickListener(v -> {
91 | LinearLayoutManager manager = (LinearLayoutManager) rec_mz.getLayoutManager();
92 | //如果超过50项直接跳到开头,不然要滚好久
93 | if(manager.findFirstVisibleItemPosition() < 50) {
94 | rec_mz.smoothScrollToPosition(0);
95 | } else {
96 | rec_mz.scrollToPosition(0);
97 | fabOutAnim();
98 | }
99 | });
100 | return view;
101 | }
102 |
103 | @Override
104 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
105 | super.onViewCreated(view, savedInstanceState);
106 | mSubscriptions = new CompositeDisposable();
107 | mData = new ArrayList<>();
108 | mAdapter = new GankMZAdapter(getActivity(), mData);
109 | rec_mz.setAdapter(mAdapter);
110 | srl_refresh.setRefreshing(true);
111 | fetchGankMZ(true);
112 | }
113 |
114 |
115 | @Override
116 | public void onDestroy() {
117 | super.onDestroy();
118 | mSubscriptions.clear();
119 | }
120 |
121 | /* 拉取妹子数据 */
122 | private void fetchGankMZ(boolean isRefresh) {
123 | Disposable subscribe = APIService.getInstance().apis.fetchGankMZ(20, mCurPage)
124 | .subscribeOn(Schedulers.io())
125 | .observeOn(AndroidSchedulers.mainThread())
126 | .doOnSubscribe(subscription -> srl_refresh.setRefreshing(true))
127 | .doFinally(() -> srl_refresh.setRefreshing(false))
128 | .subscribe(data -> {
129 | if(data != null && data.getResults() != null && data.getResults().size() > 0) {
130 | ArrayList results = data.getResults();
131 | if (isRefresh) {
132 | mAdapter.addAll(results);
133 | ToastUtils.shortToast(ResUtils.getString(R.string.refresh_success));
134 | } else {
135 | mAdapter.loadMore(results);
136 | String msg = String.format(ResUtils.getString(R.string.load_more_num),results.size(),"妹子");
137 | ToastUtils.shortToast(msg);
138 | }
139 | }
140 | }, RxSchedulers::processRequestException);
141 | mSubscriptions.add(subscribe);
142 | }
143 |
144 | /* 悬浮按钮显示动画 */
145 | private void fabInAnim() {
146 | if (fab_top.getVisibility() == View.GONE) {
147 | fab_top.setVisibility(View.VISIBLE);
148 | ViewCompat.animate(fab_top).scaleX(1.0F).scaleY(1.0F).alpha(1.0F)
149 | .setInterpolator(INTERPOLATOR).withLayer().setListener(null).start();
150 | }
151 | }
152 |
153 | /* 悬浮图标隐藏动画 */
154 | private void fabOutAnim() {
155 | if (fab_top.getVisibility() == View.VISIBLE) {
156 | ViewCompat.animate(fab_top).scaleX(0.0F).scaleY(0.0F).alpha(0.0F)
157 | .setInterpolator(INTERPOLATOR).withLayer().setListener(new ViewPropertyAnimatorListener() {
158 | @Override
159 | public void onAnimationStart(View view) {
160 |
161 | }
162 |
163 | @Override
164 | public void onAnimationEnd(View view) {
165 | fab_top.setVisibility(View.GONE);
166 | }
167 |
168 | @Override
169 | public void onAnimationCancel(View view) {
170 |
171 | }
172 | }).start();
173 | }
174 | }
175 |
176 | }
177 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_setting.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
28 |
29 |
37 |
38 |
47 |
48 |
58 |
59 |
68 |
69 |
78 |
79 |
80 |
90 |
91 |
100 |
101 |
110 |
111 |
121 |
122 |
131 |
132 |
142 |
143 |
152 |
153 |
163 |
164 |
173 |
174 |
184 |
185 |
194 |
195 |
--------------------------------------------------------------------------------