├── .gitignore
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── libs
│ └── universal-image-loader-1.9.3-SNAPSHOT.jar
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── tk
│ │ └── wlemuel
│ │ └── cotable
│ │ ├── ApplicationTest.java
│ │ ├── ExampleTest.java
│ │ └── utils
│ │ └── TLogTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ ├── content-template.html
│ ├── content.html
│ ├── font-big.css
│ ├── font-middle.css
│ ├── font-small.css
│ ├── style-day.css
│ └── style-night.css
│ ├── java
│ ├── android
│ │ └── support
│ │ │ └── v4
│ │ │ └── widget
│ │ │ └── MySwipeRefreshLayout.java
│ └── tk
│ │ └── wlemuel
│ │ └── cotable
│ │ ├── activity
│ │ ├── MainActivity.java
│ │ ├── News
│ │ │ ├── adapter
│ │ │ │ └── NewsAdapter.java
│ │ │ └── fragment
│ │ │ │ └── NewsFragment.java
│ │ ├── SplashActivity.java
│ │ ├── blog
│ │ │ ├── BlogTab.java
│ │ │ ├── adapter
│ │ │ │ ├── BlogAdapter.java
│ │ │ │ └── BlogTabPagerAdapter.java
│ │ │ ├── fragment
│ │ │ │ ├── BlogDetailFragment.java
│ │ │ │ ├── BlogListFragment.java
│ │ │ │ └── BlogViewPagerFragment.java
│ │ │ └── view
│ │ │ │ └── DetailActivity.java
│ │ ├── common
│ │ │ └── SimpleBackActivity.java
│ │ ├── image
│ │ │ └── ImagePreviewActivity.java
│ │ ├── settings
│ │ │ └── fragment
│ │ │ │ ├── AboutFragment.java
│ │ │ │ └── SettingFragment.java
│ │ └── view
│ │ │ ├── CoScrollView.java
│ │ │ ├── ReaderWebView.java
│ │ │ └── ScrollDirectionListener.java
│ │ ├── api
│ │ ├── ApiClientHelper.java
│ │ ├── ApiHttpClient.java
│ │ ├── BaseApi.java
│ │ ├── BlogApi.java
│ │ └── NewsApi.java
│ │ ├── base
│ │ ├── BaseActivity.java
│ │ ├── BaseApplication.java
│ │ ├── BaseDetailFragment.java
│ │ ├── BaseFragment.java
│ │ ├── BaseListAdapter.java
│ │ ├── BaseRecycleAdapter.java
│ │ ├── BaseRecycleViewFragment.java
│ │ └── BaseTabFragment.java
│ │ ├── cache
│ │ └── CacheManager.java
│ │ ├── core
│ │ ├── AppConfig.java
│ │ ├── AppContext.java
│ │ ├── AppException.java
│ │ └── AppManager.java
│ │ ├── model
│ │ ├── Base.java
│ │ ├── Blog.java
│ │ ├── BlogDetail.java
│ │ ├── BlogList.java
│ │ ├── DrawerMenu.java
│ │ ├── Entity.java
│ │ ├── ListEntity.java
│ │ ├── News.java
│ │ └── SimpleBackPage.java
│ │ ├── ui
│ │ ├── customWidget
│ │ │ └── CircleImageView.java
│ │ ├── decorator
│ │ │ └── DividerItemDecoration.java
│ │ ├── dialog
│ │ │ ├── DialogControl.java
│ │ │ └── WaitDialog.java
│ │ ├── drawer
│ │ │ ├── DrawerMenuAdapter.java
│ │ │ └── DrawerMenuHolder.java
│ │ ├── empty
│ │ │ └── EmptyLayout.java
│ │ ├── pagertab
│ │ │ ├── PagerSlidingTabStrip.java
│ │ │ ├── SlidingTabPagerAdapter.java
│ │ │ ├── q.java
│ │ │ └── r.java
│ │ └── widget
│ │ │ └── FixedRecyclerView.java
│ │ └── utils
│ │ ├── BlogReaderAnim.java
│ │ ├── CircleBitmapDisplayer.java
│ │ ├── CyptoUtils.java
│ │ ├── HtmlUtils.java
│ │ ├── OnWebViewImageListener.java
│ │ ├── StringUtils.java
│ │ ├── TDevice.java
│ │ ├── TLog.java
│ │ ├── TimeZoneUtil.java
│ │ ├── UIHelper.java
│ │ └── ViewUtils.java
│ └── res
│ ├── anim
│ └── progressbar_loading.xml
│ ├── drawable-hdpi
│ ├── ic_add_white_24dp.png
│ ├── ic_comment.png
│ ├── ic_comment_active.png
│ ├── ic_dianzan.png
│ ├── ic_dianzan_active.png
│ ├── ic_launcher.png
│ ├── ic_pullrefresh.png
│ ├── ic_reply.png
│ ├── ic_reply_active.png
│ ├── ic_scrolltoup_24dp.png
│ ├── main_bottombtn_down.9.png
│ ├── main_bottombtn_up.9.png
│ ├── main_icon_zoomin.png
│ ├── main_icon_zoomin_dis.png
│ ├── main_icon_zoomout.png
│ ├── main_icon_zoomout_dis.png
│ ├── main_topbtn_down.9.png
│ ├── main_topbtn_up.9.png
│ ├── main_zoomin.xml
│ ├── main_zoomout.xml
│ ├── spinner_48_inner_holo.png
│ └── spinner_48_outer_holo.png
│ ├── drawable-mdpi
│ ├── ic_avatar_author.png
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ ├── actionbar_back_icon_normal.png
│ ├── animdraw.xml
│ ├── bg_splash_bg.png
│ ├── btn_menu_about_normal.png
│ ├── btn_menu_about_pressed.png
│ ├── btn_menu_close_normal.png
│ ├── btn_menu_close_pressed.png
│ ├── btn_menu_day_pressed.png
│ ├── btn_menu_daymode_normal.png
│ ├── btn_menu_night_normal.png
│ ├── btn_menu_night_pressed.png
│ ├── btn_menu_options_normal.png
│ ├── btn_menu_options_pressed.png
│ ├── drawer_left_header.jpg
│ ├── ic_avatar_author.png
│ ├── ic_blog_item_avatar.png
│ ├── ic_default_avatar.png
│ ├── ic_launcher.png
│ ├── loadingpage_bg.png
│ ├── loadingpage_light.png
│ ├── page_icon_network.png
│ ├── pagefailed_bg.png
│ └── tab_notification_bg.9.png
│ ├── drawable-xxhdpi
│ ├── ic_avatar_author.png
│ └── ic_launcher.png
│ ├── drawable
│ ├── bg_drawer_left_list_item.xml
│ ├── list_cell_background_selector.xml
│ ├── main_bottombutton.xml
│ ├── main_topbutton.xml
│ ├── progress_medium_holo.xml
│ └── tab_strip_background.xml
│ ├── layout
│ ├── activity_main.xml
│ ├── activity_main_blog_list.xml
│ ├── activity_main_blog_list_item.xml
│ ├── activity_main_drawer_left.xml
│ ├── activity_main_drawer_left_divider.xml
│ ├── activity_main_drawer_left_list_group.xml
│ ├── activity_main_drawer_left_list_item.xml
│ ├── activity_main_drawer_left_setting_bar.xml
│ ├── aty_detail.xml
│ ├── aty_simple_fragment.xml
│ ├── aty_splash_background.xml
│ ├── fragment_blog_detail.xml
│ ├── fragment_swipe_refresh_recycleview.xml
│ ├── fragment_viewpager.xml
│ ├── list_cell_blog.xml
│ ├── list_cell_footer.xml
│ ├── tab_layout_main.xml
│ ├── view_error_layout.xml
│ ├── view_toast.xml
│ └── view_toolbar.xml
│ ├── menu
│ └── menu_main.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── values-en-rUS
│ └── strings.xml
│ ├── values-ja-rJP
│ └── strings.xml
│ └── values
│ ├── attrs.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── screenshot
└── screenshot.png
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 | /local.properties
3 | /.idea/workspace.xml
4 | /.idea/libraries
5 | .DS_Store
6 | /build
7 | /captures
8 |
9 | # built application files
10 | *.apk
11 | *.ap_
12 |
13 | # files for the dex VM
14 | *.dex
15 |
16 | # Java class files
17 | *.class
18 |
19 | # generated files
20 | bin/
21 | gen/
22 |
23 | # Local configuration file (sdk path, etc)
24 | local.properties
25 |
26 | # Eclipse project files
27 | .classpath
28 | .project
29 |
30 | # Proguard folder generated by Eclipse
31 | proguard/
32 |
33 | # Intellij project files
34 | *.iml
35 | *.ipr
36 | *.iws
37 | .idea/
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Cotable - Yet Another Cnblogs Client for Android
2 |
3 | [](https://gitter.im/Lemueler/Cotable?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4 |
5 | ## Description
6 | Cotable = Code + Stable (The Paradise of Coder)
7 |
8 | The Android client of Cnblogs that named as "Cotable", the reason why I decided to make this baby is that I want to learn Android development and I like read the blogs at "www.cnblogs.com" as well. I do hope u could join me to make this application better.
9 |
10 |
11 | ## ScreenShot
12 |
13 | 
14 |
15 | ## Features
16 | It can store the cache into you device automatically, so that if you have viewed a blog before, you could view it without the internet connection next time.
17 |
18 |
19 | ## Upgrade Notes
20 | ### v1.0
21 | Provide the basic functions like read the lastest blog and latest news and the recommend blogs.
22 |
23 |
24 | ## TODO (wish list)
25 | 1. Add the login functions.
26 | 2. Make the blogs read by catalogs. (Need web api support, Maybe I will write it depending on Python+Django).
27 | 3. View the comment of current blog or news.
28 | 4. Post a new blog to the Cnblogs.
29 | 5. Add the night read mode.
30 | 6. ...
31 |
32 |
33 | ## Thanks
34 | 1. [android-app](http://git.oschina.net/tonlin/android-app):
35 | A lot of codes were borrowed from this project.
36 | 2. [android-async-http](https://github.com/loopj/android-async-http): An Asynchronous HTTP Library for Android.
37 | 3. [floatingactionbutton](https://github.com/makovkastar/FloatingActionButton): Android floating action button.
38 |
39 | ## License
40 |
41 | Copyright 2015 Steve Lemuel
42 |
43 | Licensed under the Apache License, Version 2.0 (the "License");
44 | you may not use this file except in compliance with the License.
45 | You may obtain a copy of the License at
46 |
47 | http://www.apache.org/licenses/LICENSE-2.0
48 |
49 | Unless required by applicable law or agreed to in writing, software
50 | distributed under the License is distributed on an "AS IS" BASIS,
51 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
52 | See the License for the specific language governing permissions and
53 | limitations under the License.
54 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 21
5 | buildToolsVersion "22.0.1"
6 |
7 | defaultConfig {
8 | applicationId "tk.wlemuel.cotable"
9 | minSdkVersion 9
10 | targetSdkVersion 21
11 | versionCode 1
12 | versionName "1.0-Alpha"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', exclude: ['x.jar'], include: ['*.jar'])
24 | compile 'com.android.support:appcompat-v7:21.0.3'
25 | compile 'com.android.support:recyclerview-v7:21.0.3'
26 | compile 'com.joanzapata.android:android-iconify:1.0.8'
27 | compile 'de.hdodenhof:circleimageview:1.2.2'
28 | compile 'com.loopj.android:android-async-http:1.4.6'
29 | compile 'com.melnykov:floatingactionbutton:1.3.0'
30 |
31 | // compile 'com.github.johnpersano:supertoasts:1.3.4@aar'
32 | // compile 'com.github.johnkil.android-appmsg:appmsg:1.2.0'
33 | // compile 'com.balysv.materialmenu:material-menu-abc:1.5.1'
34 | // compile 'in.srain.cube:ultra-ptr:1.0.9@aar'
35 | // compile 'be.webelite:ion-iconview:1.0.+@aar'
36 | // compile 'com.github.traex.calendarlistview:library:1.2.2'
37 | // compile 'com.github.navasmdc:MaterialDesign:1.+@aar'
38 | // compile 'com.balysv.materialmenu:material-menu:1.5.1'
39 | // compile 'com.github.manuelpeinado.fadingactionbar:fadingactionbar:3.1.2'
40 | // compile 'com.getbase:floatingactionbutton:1.9.0'
41 | // compile 'com.oguzdev:CircularFloatingActionMenu:1.0.2'
42 | // compile 'com.specyci:residemenu:1.6+'
43 | // compile 'com.arasthel:gnavdrawer-library:+'
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/app/libs/universal-image-loader-1.9.3-SNAPSHOT.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/libs/universal-image-loader-1.9.3-SNAPSHOT.jar
--------------------------------------------------------------------------------
/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 /Volumes/Extend/Development/android-sdk-macosx/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 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/tk/wlemuel/cotable/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable;
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/androidTest/java/tk/wlemuel/cotable/ExampleTest.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable;
2 |
3 | /**
4 | * ExampleTest
5 | *
6 | * @author Steve Lemuel
7 | * @version 0.1
8 | * @desc ExampleTest
9 | * @created 2015/05/19
10 | * @updated 2015/05/19
11 | */
12 | public class ExampleTest {
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/tk/wlemuel/cotable/utils/TLogTest.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.utils;
2 |
3 | import junit.framework.TestCase;
4 |
5 | /**
6 | * TLogTest
7 | *
8 | * @author Steve Lemuel
9 | * @version 0.1
10 | * @desc TLogTest
11 | * @created 2015/05/19
12 | * @updated 2015/05/19
13 | */
14 | public class TLogTest extends TestCase {
15 |
16 | public void setUp() throws Exception {
17 | super.setUp();
18 |
19 | }
20 |
21 | public void tearDown() throws Exception {
22 |
23 | }
24 |
25 | public void testAnalytics() throws Exception {
26 |
27 | }
28 |
29 | public void testError() throws Exception {
30 |
31 | }
32 |
33 | public void testLog() throws Exception {
34 |
35 | }
36 |
37 | public void testLog1() throws Exception {
38 |
39 | }
40 |
41 | public void testLogv() throws Exception {
42 |
43 | }
44 |
45 | public void testWarning() throws Exception {
46 |
47 | }
48 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
34 |
35 |
36 |
37 |
40 |
41 |
42 |
43 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/assets/content-template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | Cnblogs
8 |
9 |
10 |
11 |
12 |
13 |
14 |
19 |
20 |
21 | {%Content%}
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/src/main/assets/content.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | cnblogs
4 |
6 |
7 |
8 |
9 |
10 | {%Content%}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/assets/font-big.css:
--------------------------------------------------------------------------------
1 | #content{ line-height:1.8; font-size:12pt;}
2 | pre{font-size:9pt;}
3 |
--------------------------------------------------------------------------------
/app/src/main/assets/font-middle.css:
--------------------------------------------------------------------------------
1 | #content{ line-height:1.8; font-size:9pt;}
2 | pre{font-size:7pt;}
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/assets/font-small.css:
--------------------------------------------------------------------------------
1 | #content{ line-height:1.8; font-size:7pt;}
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/assets/style-day.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #777;
3 | font-family: Helvetica,"Microsoft Yahei",Verdana,Helvetica,SimSun,Arial,"Arial Unicode MS", MingLiu,PMingLiu,"MS Gothic",sans-serief;
4 | margin: 0 auto;
5 | }
6 |
7 | .pure-img-responsive {
8 | max-width: 100%;
9 | height: auto;
10 | }
11 |
12 | #layout {
13 | position: relative;
14 | padding-left: 0;
15 | }
16 |
17 | .content {
18 | margin: 0 auto;
19 | padding: 0 1em;
20 | max-width: 800px;
21 | margin-bottom: 50px;
22 | line-height: 1.6em;
23 | }
24 |
25 | .header {
26 | margin: 0 auto;
27 | color: #333;
28 | text-align: center;
29 | padding: 1em 1em 0;
30 | border-bottom: 1px solid #eee;
31 | background-color: #2196F3;
32 | color: #FFFFFF;
33 | }
34 |
35 | .header h1 {
36 | text-align: left;
37 | margin: 0.2em 0;
38 | font-size: 1.5em;
39 | font-weight: 300;
40 | }
41 | .header h2 {
42 | text-align: left;
43 | font-weight: 300;
44 | padding: 0;
45 | font-size: 0.8em;
46 | margin-top: 0;
47 | }
48 |
49 | p {
50 | margin-top: 0;
51 | margin-bottom: 5pt;
52 | line-height: 1.6em;
53 | }
54 |
55 | img {
56 | max-width: 90%;
57 | height: auto;
58 | }
59 |
60 | div.bimg {
61 | text-align: center;
62 | padding: 0;
63 | }
64 |
65 | audio {
66 | width: 100%
67 | }
68 |
69 | * {
70 | -webkit-touch-callout: none;
71 | /* prevent callout to copy image, etc when tap to hold */
72 | /*-webkit-text-size-adjust: none;*/ /* prevent webkit from resizing text to fit */
73 | -webkit-tap-highlight-color: rgba(0,0,0,0.15);
74 | /* make transparent link selection, adjust last value opacity 0 to 1.0 */
75 | /*-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
76 | }
--------------------------------------------------------------------------------
/app/src/main/assets/style-night.css:
--------------------------------------------------------------------------------
1 | body{font-family:Helvetica,"Microsoft Yahei",Verdana,Helvetica,SimSun,Arial,"Arial Unicode MS",MingLiu,PMingLiu,"MS Gothic",sans-serief;margin:0;padding:8px; background-color:#25262b; color:#8590A2;word-wrap:break-word;}
2 | a{ color:#1799ff;}
3 | p{margin-top:0;margin-bottom:5pt;line-height: 1.6em;}
4 | img{max-width:90%;height:auto;}
5 | div.bimg{text-align:center;padding:0;}
6 | audio{width:100%}
7 | *{-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
8 | /*-webkit-text-size-adjust: none;*/ /* prevent webkit from resizing text to fit */
9 | -webkit-tap-highlight-color: rgba(0,0,0,0.0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
10 | /*-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/MainActivity.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.widget.DrawerLayout;
5 | import android.support.v7.app.ActionBarDrawerToggle;
6 | import android.support.v7.widget.Toolbar;
7 | import android.view.KeyEvent;
8 | import android.view.Menu;
9 | import android.view.MenuItem;
10 | import android.view.View;
11 | import android.widget.AdapterView;
12 | import android.widget.LinearLayout;
13 | import android.widget.ListView;
14 |
15 | import com.joanzapata.android.iconify.IconDrawable;
16 | import com.joanzapata.android.iconify.Iconify;
17 |
18 | import java.util.ArrayList;
19 | import java.util.List;
20 |
21 | import tk.wlemuel.cotable.R;
22 | import tk.wlemuel.cotable.base.BaseActivity;
23 | import tk.wlemuel.cotable.core.AppConfig;
24 | import tk.wlemuel.cotable.model.DrawerMenu;
25 | import tk.wlemuel.cotable.ui.drawer.DrawerMenuAdapter;
26 |
27 |
28 | public class MainActivity extends BaseActivity {
29 |
30 | private Toolbar mActionBar;
31 | private DrawerLayout mDrawerLayout;
32 | private ActionBarDrawerToggle mDrawerToggle;
33 |
34 | private String[] mMenuTitles;
35 | private ListView mMenuListView;
36 | private LinearLayout mDrawerLeft;
37 |
38 | @Override
39 | protected void onCreate(Bundle savedInstanceState) {
40 | super.onCreate(savedInstanceState);
41 | setContentView(R.layout.activity_main);
42 |
43 | initView(savedInstanceState);
44 |
45 | }
46 |
47 | private void initView(Bundle savedInstanceState) {
48 | initActionBar();
49 | initSlidingMenu();
50 | }
51 |
52 | /**
53 | * init the action bar.
54 | */
55 | private void initActionBar() {
56 |
57 | mActionBar = (Toolbar) findViewById(R.id.actionBar);
58 | mActionBar.setTitle(R.string.app_name);
59 | setSupportActionBar(mActionBar);
60 |
61 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
62 |
63 | }
64 |
65 | private void initSlidingMenu() {
66 | List listMenuData = new ArrayList<>();
67 |
68 | mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
69 | mDrawerLeft = (LinearLayout) findViewById(R.id.drawer_left);
70 | mDrawerToggle = new ActionBarDrawerToggle(
71 | this, mDrawerLayout, mActionBar, R.string.drawer_open,
72 | R.string.drawer_close);
73 | mDrawerToggle.syncState();
74 | mDrawerLayout.setDrawerListener(mDrawerToggle);
75 |
76 | mMenuTitles = getResources().getStringArray(R.array.menu_array);
77 | mMenuListView = (ListView) findViewById(R.id.drawer_left_list);
78 |
79 | for (String data : mMenuTitles) {
80 | DrawerMenu itemData = new DrawerMenu();
81 | itemData.setIcon("{fa-rss}");
82 | itemData.setText(data);
83 | listMenuData.add(itemData);
84 | }
85 |
86 | mMenuListView.setAdapter(new DrawerMenuAdapter(this, listMenuData));
87 | mMenuListView.setOnItemClickListener(new DrawerItemClickListener());
88 | }
89 |
90 |
91 | @Override
92 | public boolean onCreateOptionsMenu(Menu menu) {
93 | // Inflate the menu; this adds items to the action bar if it is present.
94 | getMenuInflater().inflate(R.menu.menu_main, menu);
95 |
96 | menu.findItem(R.id.action_menu_search).setIcon(
97 | new IconDrawable(this, Iconify.IconValue.fa_search)
98 | .colorRes(R.color.toolbar_text_color)
99 | .sizeDp(AppConfig.SEARCH_ICON_SIZE_PATCH)
100 | );
101 |
102 | menu.findItem(R.id.action_menu_favor).setIcon(
103 | new IconDrawable(this, Iconify.IconValue.fa_star)
104 | .colorRes(R.color.toolbar_text_color)
105 | .actionBarSize()
106 | );
107 |
108 | return super.onCreateOptionsMenu(menu);
109 | }
110 |
111 | @Override
112 | public boolean onOptionsItemSelected(MenuItem item) {
113 | // Handle action bar item clicks here. The action bar will
114 | // automatically handle clicks on the Home/Up button, so long
115 | // as you specify a parent activity in AndroidManifest.xml.
116 | int id = item.getItemId();
117 |
118 | //noinspection SimplifiableIfStatement
119 | switch (id) {
120 | case (R.id.action_menu_search):
121 |
122 |
123 | return true;
124 | case (R.id.action_menu_exit):
125 | if (!this.isFinishing())
126 | this.finish();
127 | }
128 |
129 | return super.onOptionsItemSelected(item);
130 |
131 | }
132 |
133 | @Override
134 | public boolean onKeyDown(int keyCode, KeyEvent event) {
135 | if ((keyCode == KeyEvent.KEYCODE_BACK)) {
136 | if (mDrawerLayout.isDrawerOpen(mDrawerLeft)) {
137 | mDrawerLayout.closeDrawer(mDrawerLeft);
138 | return true;
139 | }
140 | } else if ((keyCode == KeyEvent.KEYCODE_MENU)) {
141 | if (mDrawerLayout.isDrawerOpen(mDrawerLeft)) {
142 | mDrawerLayout.closeDrawer(mDrawerLeft);
143 | } else {
144 | mDrawerLayout.openDrawer(mDrawerLeft);
145 | }
146 | return true;
147 | }
148 | return super.onKeyDown(keyCode, event);
149 | }
150 |
151 | private void selectItem(int position) {
152 | // mMenuListView.setItemChecked(position, true);
153 | mDrawerLayout.closeDrawer(mDrawerLeft);
154 | }
155 |
156 | private class DrawerItemClickListener implements
157 | ListView.OnItemClickListener {
158 | @Override
159 | public void onItemClick(AdapterView> parent, View view, int position,
160 | long id) {
161 | selectItem(position);
162 | }
163 | }
164 |
165 | }
166 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/News/adapter/NewsAdapter.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.News.adapter;
2 |
3 | /**
4 | * NewsAdapter
5 | *
6 | * @author Steve Lemuel
7 | * @version 0.1
8 | * @desc NewsAdapter
9 | * @created 2015/05/09
10 | * @updated 2015/05/09
11 | */
12 | public class NewsAdapter {
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/News/fragment/NewsFragment.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.News.fragment;
2 |
3 | /**
4 | * NewsFragment
5 | *
6 | * @author Steve Lemuel
7 | * @version 0.1
8 | * @desc NewsFragment
9 | * @created 2015/05/09
10 | * @updated 2015/05/09
11 | */
12 | public class NewsFragment {
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/SplashActivity.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.view.animation.AlphaAnimation;
7 | import android.view.animation.Animation;
8 |
9 | import tk.wlemuel.cotable.R;
10 | import tk.wlemuel.cotable.base.BaseActivity;
11 | import tk.wlemuel.cotable.utils.TDevice;
12 |
13 |
14 | public class SplashActivity extends BaseActivity {
15 |
16 | public static final int MAX_WAITING_TIME = 3000; // Wait for 3 seconds
17 | private static final String SPLASH_SCREEN = "SplashScreen";
18 | protected boolean mShouldGoTo = true;
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 |
24 | TDevice.setFullScreen(this);
25 |
26 | final View view = View.inflate(this, R.layout.aty_splash_background, null);
27 | setContentView(view);
28 |
29 |
30 | AlphaAnimation aa = new AlphaAnimation(0.3f, 1.0f);
31 | aa.setDuration(MAX_WAITING_TIME);
32 | view.startAnimation(aa);
33 | aa.setAnimationListener(new Animation.AnimationListener() {
34 |
35 | @Override
36 | public void onAnimationEnd(Animation arg0) {
37 | if (mShouldGoTo) {
38 | redirectTo();
39 | }
40 | }
41 |
42 | @Override
43 | public void onAnimationRepeat(Animation animation) {
44 | }
45 |
46 | @Override
47 | public void onAnimationStart(Animation animation) {
48 | }
49 | });
50 |
51 |
52 | }
53 |
54 | private void redirectTo() {
55 | Intent intent = new Intent(this, MainActivity.class);
56 |
57 | startActivity(intent);
58 | finish();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/blog/BlogTab.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.blog;
2 |
3 | import tk.wlemuel.cotable.R;
4 | import tk.wlemuel.cotable.activity.blog.fragment.BlogListFragment;
5 | import tk.wlemuel.cotable.model.BlogList;
6 |
7 | /**
8 | * BlogTab
9 | *
10 | * @author Steve Lemuel
11 | * @version 0.1
12 | * @desc BlogTab
13 | * @created 2015/05/10
14 | * @updated 2015/05/10
15 | */
16 | public enum BlogTab {
17 | LASTEST(0, BlogList.CATALOG_LASTEST, R.string.tab_title_blog_latest, BlogListFragment.class),
18 | // RECOMMEND(1, BlogList.CATALOG_RECOMMEND, R.string.tab_title_blog_recommend,
19 | // BlogListFragment.class),
20 | NEWS(1, BlogList.CATALOG_RECOMMEND, R.string.tab_title_news_latest, BlogListFragment.class);
21 |
22 | private Class> clz;
23 | private int idx;
24 | private int title;
25 | private int catalog;
26 |
27 | BlogTab(int idx, int catalog, int title, Class> clz) {
28 | this.idx = idx;
29 | this.clz = clz;
30 | this.setCatalog(catalog);
31 | this.setTitle(title);
32 | }
33 |
34 | public static BlogTab getTabByIdx(int idx) {
35 | for (BlogTab t : values()) {
36 | if (t.getIdx() == idx)
37 | return t;
38 | }
39 | return LASTEST;
40 | }
41 |
42 | public Class> getClz() {
43 | return clz;
44 | }
45 |
46 | public void setClz(Class> clz) {
47 | this.clz = clz;
48 | }
49 |
50 | public int getIdx() {
51 | return idx;
52 | }
53 |
54 | public void setIdx(int idx) {
55 | this.idx = idx;
56 | }
57 |
58 | public int getTitle() {
59 | return title;
60 | }
61 |
62 | public void setTitle(int title) {
63 | this.title = title;
64 | }
65 |
66 | public int getCatalog() {
67 | return catalog;
68 | }
69 |
70 | public void setCatalog(int catalog) {
71 | this.catalog = catalog;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/blog/adapter/BlogAdapter.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.blog.adapter;
2 |
3 | import android.view.View;
4 | import android.view.ViewGroup;
5 | import android.widget.TextView;
6 |
7 | import de.hdodenhof.circleimageview.CircleImageView;
8 | import tk.wlemuel.cotable.R;
9 | import tk.wlemuel.cotable.base.BaseRecycleAdapter;
10 | import tk.wlemuel.cotable.model.Blog;
11 | import tk.wlemuel.cotable.utils.HtmlUtils;
12 |
13 | /**
14 | * BlogAdapter
15 | *
16 | * @author Steve Lemuel
17 | * @version 0.1
18 | * @desc BlogAdapter
19 | * @created 2015/05/08
20 | * @updated 2015/05/08
21 | */
22 | public class BlogAdapter extends BaseRecycleAdapter {
23 |
24 | @Override
25 | protected View onCreateItemView(ViewGroup parent, int viewType) {
26 | return getLayoutInflater(parent.getContext()).inflate(R.layout.list_cell_blog, null);
27 | }
28 |
29 | @Override
30 | protected ViewHolder onCreateItemViewHolder(View view, int viewType) {
31 | return new ViewHolder(viewType, view);
32 | }
33 |
34 | @Override
35 | protected void onBindItemViewHolder(BaseRecycleAdapter.ViewHolder holder, int position) {
36 | ViewHolder vh = (ViewHolder) holder;
37 |
38 | Blog item = (Blog) mData.get(position);
39 | vh.mTitle.setText(HtmlUtils.filter(item.getTitle()));
40 | vh.mSummary.setText(HtmlUtils.filter(item.getSummary()));
41 | vh.mAuthorName.setText(item.getAuthor_name());
42 | vh.mUpdated.setText(item.getUpdated());
43 | vh.mComments.setText(
44 | vh.mComments.getContext().getString(
45 | R.string.blog_item_comments_default, item.getComments())
46 | );
47 | vh.mReads.setText(
48 | vh.mComments.getContext().getString(
49 | R.string.blog_item_reading_default, item.getReads())
50 | );
51 | setAuthorAvatar(item.getBlogapp(), vh.mAuthorAvatar);
52 |
53 |
54 | }
55 |
56 | private void setAuthorAvatar(String blogapp, final CircleImageView imageView) {
57 | // BlogApi.getAuthorAvatar(blogapp, new JsonHttpResponseHandler() {
58 | // @Override
59 | // public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
60 | // try {
61 | // JSONObject info = (JSONObject) response.get("data");
62 | // String avatar = info.getString("avatar");
63 | // if (avatar != null && !avatar.equals(""))
64 | // ImageLoader.getInstance().displayImage(avatar, imageView);
65 | //
66 | // } catch (JSONException e) {
67 | // e.printStackTrace();
68 | // }
69 | // }
70 | //
71 | // @Override
72 | // public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
73 | // super.onFailure(statusCode, headers, throwable, errorResponse);
74 | // }
75 | // });
76 | //
77 |
78 | }
79 |
80 | static class ViewHolder extends BaseRecycleAdapter.ViewHolder {
81 | public TextView mTitle, mSummary, mAuthorName, mUpdated, mComments, mReads;
82 | public CircleImageView mAuthorAvatar;
83 |
84 | public ViewHolder(int viewType, View view) {
85 | super(viewType, view);
86 |
87 | mTitle = (TextView) view.findViewById(R.id.blog_title);
88 | mSummary = (TextView) view.findViewById(R.id.blog_summary);
89 | mAuthorName = (TextView) view.findViewById(R.id.blog_author_name);
90 | mUpdated = (TextView) view.findViewById(R.id.blog_updated);
91 | mComments = (TextView) view.findViewById(R.id.blog_comments);
92 | mReads = (TextView) view.findViewById(R.id.blog_reads);
93 | mAuthorAvatar = (CircleImageView) view.findViewById(R.id.blog_author_avatar);
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/blog/adapter/BlogTabPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.blog.adapter;
2 |
3 | import android.content.Context;
4 | import android.os.Bundle;
5 | import android.support.v4.app.Fragment;
6 | import android.support.v4.app.FragmentManager;
7 | import android.support.v4.view.ViewPager;
8 |
9 | import java.util.Iterator;
10 | import java.util.List;
11 |
12 | import tk.wlemuel.cotable.activity.blog.BlogTab;
13 | import tk.wlemuel.cotable.activity.blog.fragment.BlogListFragment;
14 | import tk.wlemuel.cotable.base.BaseTabFragment;
15 | import tk.wlemuel.cotable.ui.pagertab.SlidingTabPagerAdapter;
16 |
17 | /**
18 | * BlogTabPagerAdapter
19 | *
20 | * @author Steve Lemuel
21 | * @version 0.1
22 | * @desc BlogTabPagerAdapter
23 | * @created 2015/05/10
24 | * @updated 2015/05/10
25 | */
26 | public final class BlogTabPagerAdapter extends SlidingTabPagerAdapter {
27 | public BlogTabPagerAdapter(FragmentManager mgr, Context context,
28 | ViewPager viewPager) {
29 | super(mgr, BlogTab.values().length, context.getApplicationContext(),
30 | viewPager);
31 |
32 | BlogTab[] tabs = BlogTab.values();
33 |
34 | for (BlogTab tab : tabs) {
35 | Fragment fragment = null;
36 | List list = mgr.getFragments();
37 | if (list != null) {
38 | Iterator iter = list.iterator();
39 | while (iter.hasNext()) {
40 | fragment = iter.next();
41 | if (fragment.getClass() == tab.getClz())
42 | break;
43 | }
44 | }
45 |
46 | BaseTabFragment tabFragment = (BaseTabFragment) fragment;
47 | if (tabFragment == null) {
48 | try {
49 | tabFragment = (BaseTabFragment) tab.getClz().newInstance();
50 | tabFragment.setCatalog(tab.getCatalog());
51 | } catch (InstantiationException e) {
52 | e.printStackTrace();
53 | } catch (IllegalAccessException e) {
54 | e.printStackTrace();
55 | }
56 | }
57 |
58 | tabFragment.addListener(this);
59 | if (!tabFragment.isAdded()) {
60 | Bundle args = new Bundle();
61 | args.putInt(BlogListFragment.BUNDLE_KEY_CATALOG,
62 | tab.getCatalog());
63 | tabFragment.setArguments(args);
64 | }
65 | fragments[tab.getIdx()] = tabFragment;
66 | }
67 | }
68 |
69 | public final int getCacheCount() {
70 | return 2;
71 | }
72 |
73 | public final int getCount() {
74 | return BlogTab.values().length;
75 | }
76 |
77 | public final CharSequence getPageTitle(int i) {
78 | BlogTab tab = BlogTab.getTabByIdx(i);
79 | int idx = 0;
80 | CharSequence title = "";
81 | if (tab != null)
82 | idx = tab.getTitle();
83 | if (idx != 0)
84 | title = context.getText(idx);
85 | return title;
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/blog/fragment/BlogListFragment.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.blog.fragment;
2 |
3 | import android.view.View;
4 |
5 | import java.io.Serializable;
6 | import java.util.HashMap;
7 | import java.util.Map;
8 |
9 | import tk.wlemuel.cotable.activity.blog.adapter.BlogAdapter;
10 | import tk.wlemuel.cotable.api.BlogApi;
11 | import tk.wlemuel.cotable.base.BaseRecycleAdapter;
12 | import tk.wlemuel.cotable.base.BaseRecycleViewFragment;
13 | import tk.wlemuel.cotable.core.AppContext;
14 | import tk.wlemuel.cotable.model.Blog;
15 | import tk.wlemuel.cotable.model.BlogList;
16 | import tk.wlemuel.cotable.model.ListEntity;
17 | import tk.wlemuel.cotable.utils.TLog;
18 | import tk.wlemuel.cotable.utils.UIHelper;
19 |
20 | /**
21 | * BlogListFragment
22 | *
23 | * @author Steve Lemuel
24 | * @version 0.1
25 | * @desc BlogListFragment
26 | * @created 2015/05/08
27 | * @updated 2015/05/08
28 | */
29 | public class BlogListFragment extends BaseRecycleViewFragment {
30 |
31 | protected static final String TAG = BlogListFragment.class.getSimpleName();
32 |
33 | private static final String CACHE_KEY_PREFIX = "BLOG_LIST";
34 |
35 | // The max cache time set to be 12 hours
36 | private static final long MAX_CACAHE_TIME = 12 * 3600 * 1000;
37 |
38 | @Override
39 | protected boolean requestDataFromNetWork() {
40 | TLog.log(TAG, "requestDataFromNetwork");
41 | return System.currentTimeMillis()
42 | - AppContext.getRefreshTime(getCacheKey()) > MAX_CACAHE_TIME;
43 | }
44 |
45 | @Override
46 | protected BaseRecycleAdapter getListAdapter() {
47 | return new BlogAdapter();
48 | }
49 |
50 | @Override
51 | protected String getCacheKeyPrefix() {
52 | return CACHE_KEY_PREFIX;
53 | }
54 |
55 | @Override
56 | protected ListEntity parseList(String data) throws Exception {
57 | return BlogList.parse(data);
58 | }
59 |
60 | @Override
61 | protected ListEntity readList(Serializable seri) {
62 | return ((BlogList) seri);
63 | }
64 |
65 | @Override
66 | protected void sendRequestData() {
67 | if (mCatalog == BlogList.CATALOG_RECOMMEND) {
68 | BlogApi.getRecommendBlogList(mCurrentPage + 1, getResponseHandler());
69 | } else {
70 | BlogApi.getBlogList(mCurrentPage + 1, getResponseHandler());
71 | }
72 | }
73 |
74 | @Override
75 | public void onItemClick(View v, int position) {
76 | Blog blog = (Blog) mAdapter.getItem(position);
77 |
78 | Map blogInfo = new HashMap<>();
79 | blogInfo.put(BlogDetailFragment.BUNDLE_KEY_BLOG_AUTHOR, blog.getAuthor_name());
80 | blogInfo.put(BlogDetailFragment.BUNDLE_KEY_BLOG_TITLE, blog.getTitle());
81 | blogInfo.put(BlogDetailFragment.BUNDLE_KEY_BLOG_POSTED, blog.getUpdated());
82 | blogInfo.put(BlogDetailFragment.BUNDLE_KEY_BLOG_READS, blog.getReads() == 0 ? "0" : Integer
83 | .toString(blog.getReads()));
84 | blogInfo.put(BlogDetailFragment.BUNDLE_KEY_BLOG_ID, blog.getPostId());
85 |
86 |
87 | if (blog != null) {
88 | UIHelper.showBlogDetail(getActivity(), blogInfo);
89 | }
90 | }
91 |
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/blog/fragment/BlogViewPagerFragment.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.blog.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v4.app.Fragment;
6 | import android.support.v4.view.ViewPager;
7 | import android.support.v4.view.ViewPager.OnPageChangeListener;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 |
12 | import tk.wlemuel.cotable.R;
13 | import tk.wlemuel.cotable.activity.blog.adapter.BlogTabPagerAdapter;
14 | import tk.wlemuel.cotable.ui.pagertab.PagerSlidingTabStrip;
15 |
16 | /**
17 | * BlogViewPagerFragment
18 | *
19 | * @author Steve Lemuel
20 | * @version 0.1
21 | * @desc BlogViewPagerFragment
22 | * @created 2015/05/10
23 | * @updated 2015/05/10
24 | */
25 | public class BlogViewPagerFragment extends Fragment implements
26 | OnPageChangeListener {
27 |
28 | private PagerSlidingTabStrip mTabStrip;
29 | private ViewPager mViewPager;
30 | private BlogTabPagerAdapter mTabAdapter;
31 |
32 | @Override
33 | public View onCreateView(LayoutInflater inflater,
34 | @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
35 | View view = inflater.inflate(R.layout.fragment_viewpager, container,
36 | false);
37 | mTabStrip = (PagerSlidingTabStrip) view.findViewById(R.id.tabs);
38 | mViewPager = (ViewPager) view.findViewById(R.id.main_tab_pager);
39 |
40 | if (mViewPager.getAdapter() == null &&
41 | mTabAdapter == null) {
42 | mTabAdapter = new BlogTabPagerAdapter(getChildFragmentManager(),
43 | getActivity(), mViewPager);
44 | }
45 | mViewPager.setOffscreenPageLimit(mTabAdapter.getCacheCount());
46 | mViewPager.setAdapter(mTabAdapter);
47 | mViewPager.setOnPageChangeListener(this);
48 | mTabStrip.setViewPager(mViewPager);
49 |
50 | return view;
51 | }
52 |
53 | @Override
54 | public void onPageScrollStateChanged(int arg0) {
55 | mTabStrip.onPageScrollStateChanged(arg0);
56 | }
57 |
58 | @Override
59 | public void onPageScrolled(int arg0, float arg1, int arg2) {
60 | mTabStrip.onPageScrolled(arg0, arg1, arg2);
61 | mTabAdapter.onPageScrolled(arg0);
62 | }
63 |
64 | @Override
65 | public void onPageSelected(int arg0) {
66 | mTabStrip.onPageSelected(arg0);
67 | mTabAdapter.onPageSelected(arg0);
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/blog/view/DetailActivity.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.blog.view;
2 |
3 | import java.lang.ref.WeakReference;
4 |
5 | import tk.wlemuel.cotable.activity.common.SimpleBackActivity;
6 | import tk.wlemuel.cotable.base.BaseFragment;
7 |
8 | /**
9 | * DetailActivity
10 | *
11 | * @author Steve Lemuel
12 | * @version 0.1
13 | * @desc DetailActivity
14 | * @created 2015/05/11
15 | * @updated 2015/05/11
16 | */
17 | public class DetailActivity extends SimpleBackActivity {
18 |
19 | public static final int DISPLAY_BLOG = 0;
20 | public static final int DIESPLAY_NEWS = 1;
21 | public static final String BUNDLE_KEY_DISPLAY_TYPE = "BUNDLE_KEY_DISPLAY_TYPE";
22 |
23 | private WeakReference mFragment;
24 |
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/common/SimpleBackActivity.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.common;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.v4.app.Fragment;
6 | import android.support.v4.app.FragmentTransaction;
7 |
8 | import java.lang.ref.WeakReference;
9 |
10 | import tk.wlemuel.cotable.R;
11 | import tk.wlemuel.cotable.base.BaseActivity;
12 | import tk.wlemuel.cotable.base.BaseFragment;
13 | import tk.wlemuel.cotable.model.SimpleBackPage;
14 |
15 | /**
16 | * SimpleBackActivity
17 | *
18 | * @author Steve Lemuel
19 | * @version 0.1
20 | * @desc SimpleBackActivity
21 | * @created 2015/05/11
22 | * @updated 2015/05/11
23 | */
24 | public class SimpleBackActivity extends BaseActivity {
25 |
26 | public final static String BUNDLE_KEY_PAGE = "BUNDLE_KEY_PAGE";
27 | public final static String BUNDLE_KEY_ARGS = "BUNDLE_KEY_ARGS";
28 | private static final String TAG = SimpleBackActivity.class.getSimpleName();
29 | private WeakReference mFragment;
30 |
31 | @Override
32 | protected int getLayoutRes() {
33 | return R.layout.aty_simple_fragment;
34 | }
35 |
36 | @Override
37 | protected boolean hasBackButton() {
38 | return true;
39 | }
40 |
41 | @Override
42 | protected boolean hasActionBar() {
43 | return true;
44 | }
45 |
46 | @Override
47 | protected void init(Bundle savedInstanceState) {
48 | super.init(savedInstanceState);
49 |
50 | Intent data = getIntent();
51 |
52 | if (data == null) {
53 | throw new RuntimeException("You must specify a page info to display.");
54 | }
55 |
56 | int pageValue = data.getIntExtra(BUNDLE_KEY_PAGE, 0);
57 | SimpleBackPage page = SimpleBackPage.getPageByValue(pageValue);
58 | if (page == null) {
59 | throw new IllegalArgumentException("Can not find page by value: " + pageValue);
60 | }
61 |
62 | setActionBarTitle(page.getTitle());
63 |
64 | try {
65 | Fragment fragment = (Fragment) page.getClz().newInstance();
66 |
67 | Bundle args = data.getBundleExtra(BUNDLE_KEY_ARGS);
68 | if (args != null) {
69 | fragment.setArguments(args);
70 | }
71 |
72 |
73 | FragmentTransaction trans = getSupportFragmentManager()
74 | .beginTransaction();
75 | trans.replace(R.id.container, fragment, TAG);
76 | trans.commit();
77 |
78 | mFragment = new WeakReference(fragment);
79 |
80 | } catch (Exception e) {
81 | e.printStackTrace();
82 | throw new IllegalArgumentException(
83 | "generate fragment error. by value:" + pageValue);
84 | }
85 | }
86 |
87 | @Override
88 | public void onBackPressed() {
89 | if (mFragment != null && mFragment.get() != null
90 | && mFragment.get() instanceof BaseFragment) {
91 | BaseFragment bf = (BaseFragment) mFragment.get();
92 | if (!bf.onBackPressed()) {
93 | super.onBackPressed();
94 | }
95 | } else {
96 | super.onBackPressed();
97 | }
98 | }
99 |
100 | @Override
101 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
102 | super.onActivityResult(requestCode, resultCode, data);
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/image/ImagePreviewActivity.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.image;
2 |
3 | /**
4 | * ImagePreviewActivity
5 | *
6 | * @author Steve Lemuel
7 | * @version 0.1
8 | * @desc ImagePreviewActivity
9 | * @created 2015/05/14
10 | * @updated 2015/05/14
11 | */
12 | public class ImagePreviewActivity {
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/settings/fragment/AboutFragment.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.settings.fragment;
2 |
3 | import tk.wlemuel.cotable.base.BaseFragment;
4 |
5 | /**
6 | * AboutFragment
7 | *
8 | * @author Steve Lemuel
9 | * @version 0.1
10 | * @desc AboutFragment
11 | * @created 2015/05/12
12 | * @updated 2015/05/12
13 | */
14 | public class AboutFragment extends BaseFragment {
15 |
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/settings/fragment/SettingFragment.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.settings.fragment;
2 |
3 | /**
4 | * SettingFragment
5 | *
6 | * @author Steve Lemuel
7 | * @version 0.1
8 | * @desc SettingFragment
9 | * @created 2015/05/12
10 | * @updated 2015/05/12
11 | */
12 | public class SettingFragment {
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/view/CoScrollView.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.view;
2 |
3 | import android.content.Context;
4 | import android.os.Build;
5 | import android.util.AttributeSet;
6 | import android.view.MotionEvent;
7 | import android.widget.ScrollView;
8 |
9 | /**
10 | * Created by Johnnyz Zhang on 2015/6/26.
11 | */
12 | public class CoScrollView extends ScrollView {
13 | private float mLastMotionY;
14 | private int mInitialScrollCheckY;
15 | private boolean mIsMoving;
16 | private static final int SCROLL_CHECK_DELAY = 100;
17 |
18 | private ScrollDirectionListener mScrollDirectionListener;
19 |
20 | public CoScrollView(Context context) {
21 | super(context);
22 | }
23 |
24 | public CoScrollView(Context context, AttributeSet attrs) {
25 | super(context, attrs);
26 | }
27 |
28 | public CoScrollView(Context context, AttributeSet attrs, int defStyle) {
29 | super(context, attrs, defStyle);
30 | }
31 |
32 | public void setScrollDirectionListener(ScrollDirectionListener listener) {
33 | mScrollDirectionListener = listener;
34 | }
35 |
36 | @Override
37 | public boolean onTouchEvent(MotionEvent event) {
38 | if (mScrollDirectionListener != null) {
39 | int action = event.getAction() & MotionEvent.ACTION_MASK;
40 |
41 | switch (action) {
42 | case MotionEvent.ACTION_MOVE :
43 | if (mIsMoving) {
44 | int yDiff = (int) (event.getY() - mLastMotionY);
45 | if (yDiff < 0) {
46 | mScrollDirectionListener.onScrollDown();
47 | } else if (yDiff > 0) {
48 | mScrollDirectionListener.onScrollUp();
49 | }
50 | mLastMotionY = event.getY();
51 | } else {
52 | mIsMoving = true;
53 | mLastMotionY = event.getY();
54 | }
55 | break;
56 |
57 | case MotionEvent.ACTION_UP:
58 | if (mIsMoving) {
59 | mIsMoving = false;
60 | startScrollCheck();
61 | }
62 | break;
63 |
64 | default :
65 | mIsMoving = false;
66 | break;
67 | }
68 | }
69 |
70 | return super.onTouchEvent(event);
71 | }
72 |
73 | private void startScrollCheck() {
74 | mInitialScrollCheckY = getScrollY();
75 | post(mScrollTask);
76 | }
77 |
78 | private final Runnable mScrollTask = new Runnable() {
79 | @Override
80 | public void run() {
81 | if (mInitialScrollCheckY == getScrollY()) {
82 | if (mScrollDirectionListener != null) {
83 | mScrollDirectionListener.onScrollCompleted();
84 | }
85 | } else {
86 | mInitialScrollCheckY = getScrollY();
87 | postDelayed(mScrollTask, SCROLL_CHECK_DELAY);
88 | }
89 | }
90 | };
91 |
92 |
93 | public boolean canScrollUp() {
94 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && canScrollVertically(-1);
95 | }
96 | public boolean canScrollDown() {
97 | return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && canScrollVertically(1);
98 | }
99 | }
100 |
101 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/activity/view/ScrollDirectionListener.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.activity.view;
2 |
3 | /**
4 | * Created by Administrator on 2015/6/26.
5 | */
6 | public interface ScrollDirectionListener {
7 | public void onScrollUp();
8 | public void onScrollDown();
9 | public void onScrollCompleted();
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/api/ApiClientHelper.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.api;
2 |
3 | /**
4 | * ApiClientHelper
5 | *
6 | * @author Steve Lemuel
7 | * @version 0.1
8 | * @desc ApiClientHelper
9 | * @created 2015/05/08
10 | * @updated 2015/05/08
11 | */
12 | public class ApiClientHelper {
13 |
14 | /**
15 | * Returns the user agent.
16 | *
17 | * @return User-agent
18 | */
19 | public static String getUserAgent() {
20 | return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like " +
21 | "Gecko) Chrome/42.0.2311.135 Safari/537.36";
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/api/BaseApi.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.api;
2 |
3 | import tk.wlemuel.cotable.core.AppConfig;
4 |
5 | /**
6 | * BaseApi
7 | *
8 | * @author Steve Lemuel
9 | * @version 0.1
10 | * @desc BaseApi
11 | * @created 2015/05/08
12 | * @updated 2015/05/08
13 | */
14 | public class BaseApi {
15 |
16 | public static final String TAG = BaseApi.class.getSimpleName();
17 |
18 | public static final String HOST = "cnblogs.davismy.com";
19 | public static final String DEFAULT_API_URL = "cnblogs.davismy.com/Handler.ashx?op=%s";
20 |
21 | protected static final String UTF8 = AppConfig.UTF8;
22 | protected final static String FLAG_ITEMCOUNT = "{ITEMCOUNT}";
23 | protected final static String FLAG_CONTENTID = "{CONTENTID}";
24 | protected final static String FLAG_PAGEINDEX = "{PAGEINDEX}";
25 | protected final static String FLAG_PAGESIZE = "{PAGESIZE}";
26 | protected final static String FLAG_BLOGAPP = "{BLOGAPP}";
27 | protected final static String FLAG_POSTID = "{POSTID}";
28 | protected final static String FLAG_TERM = "{TERM}";
29 | // Api (NEWS)
30 |
31 |
32 | // Api (BLOG)
33 | protected final static String RECOMMEND_BLOGS_PAGED = "GetTimeLine&page={PAGEINDEX}";
34 | protected final static String RECENT_BLOGS_PAGED = "GetTimeLine&page={PAGEINDEX}";
35 | protected final static String BLOG_CONTENTS = "GetBlogContent&blog_id={POSTID}";
36 |
37 | protected final static String GET_USER_INFO = "GetUserInfo&blogapp={BLOGAPP}";
38 |
39 | protected static String API_URL = DEFAULT_API_URL;
40 |
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/api/BlogApi.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.api;
2 |
3 | import com.loopj.android.http.AsyncHttpResponseHandler;
4 |
5 | import tk.wlemuel.cotable.core.AppConfig;
6 | import tk.wlemuel.cotable.utils.TLog;
7 |
8 | /**
9 | * BlogApi
10 | *
11 | * @author Steve Lemuel
12 | * @version 0.1
13 | * @desc BlogApi
14 | * @created 2015/05/09
15 | * @updated 2015/05/09
16 | */
17 | public class BlogApi extends BaseApi {
18 |
19 | public static final String TAG = BlogApi.class.getSimpleName();
20 |
21 | public static void getBlogList(int page, AsyncHttpResponseHandler handler) {
22 |
23 | String relativeUrl = RECENT_BLOGS_PAGED.replace(FLAG_PAGEINDEX, Integer.toString(page))
24 | .replace(FLAG_PAGESIZE, Integer.toString(AppConfig.DEFAULT_PAGE_SIZE));
25 |
26 | TLog.log("Start request data with the method of getBlogList");
27 |
28 | ApiHttpClient.get(relativeUrl, handler);
29 | }
30 |
31 | public static void getRecommendBlogList(int page, AsyncHttpResponseHandler handler) {
32 |
33 | String partUrl = RECOMMEND_BLOGS_PAGED.replace(FLAG_PAGEINDEX, Integer.toString(page))
34 | .replace(FLAG_PAGESIZE, Integer.toString(AppConfig.DEFAULT_PAGE_SIZE));
35 |
36 | ApiHttpClient.get(partUrl, handler);
37 | }
38 |
39 | public static void getBlogDetail(String postId, AsyncHttpResponseHandler handler) {
40 | String partUrl = BLOG_CONTENTS.replace(FLAG_POSTID, postId);
41 |
42 | ApiHttpClient.get(partUrl, handler);
43 | }
44 |
45 | public static void getAuthorAvatar(String blogapp, AsyncHttpResponseHandler handler) {
46 | String partUrl = GET_USER_INFO.replace(FLAG_BLOGAPP, blogapp);
47 |
48 | ApiHttpClient.get(partUrl, handler);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/api/NewsApi.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.api;
2 |
3 | /**
4 | * NewsApi
5 | *
6 | * @author Steve Lemuel
7 | * @version 0.1
8 | * @desc NewsApi
9 | * @created 2015/05/09
10 | * @updated 2015/05/09
11 | */
12 | public class NewsApi extends BaseApi{
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/base/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.base;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.ActionBarActivity;
5 | import android.support.v7.widget.Toolbar;
6 | import android.view.LayoutInflater;
7 | import android.view.MenuItem;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.view.Window;
11 |
12 | import tk.wlemuel.cotable.R;
13 | import tk.wlemuel.cotable.utils.TDevice;
14 |
15 | /**
16 | * BaseActivity
17 | *
18 | * @author Steve Lemuel
19 | * @version 0.1
20 | * @desc BaseActivity
21 | * @created 2015/05/11
22 | * @updated 2015/05/11
23 | */
24 | public abstract class BaseActivity extends ActionBarActivity {
25 |
26 | protected LayoutInflater mInflater;
27 | private Toolbar mActionBar;
28 |
29 | @Override
30 | protected void onCreate(Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 |
33 | if (!hasActionBar()) {
34 | supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
35 | }
36 |
37 | onBeforeSetContentLayout();
38 |
39 | if (getLayoutRes() != 0)
40 | setContentView(getLayoutRes());
41 |
42 | mActionBar = (Toolbar) findViewById(R.id.actionBar);
43 | mInflater = getLayoutInflater();
44 |
45 | if (hasActionBar())
46 | initActionBar(mActionBar);
47 |
48 | init(savedInstanceState);
49 |
50 | }
51 |
52 | @Override
53 | protected void onDestroy() {
54 | super.onDestroy();
55 | }
56 |
57 | protected void onBeforeSetContentLayout() {
58 |
59 | }
60 |
61 | protected boolean hasActionBar() {
62 | return true;
63 | }
64 |
65 | protected int getLayoutRes() {
66 | return 0;
67 | }
68 |
69 | protected View inflateView(int resId) {
70 | return mInflater.inflate(resId, null);
71 | }
72 |
73 | protected int getActionBarTitle() {
74 | return R.string.app_name;
75 | }
76 |
77 | public void setActionBarTitle(String title) {
78 | if (hasActionBar()) {
79 | if (mActionBar != null)
80 | mActionBar.setTitle(title);
81 | }
82 |
83 | if (getSupportActionBar() != null)
84 | getSupportActionBar().setTitle(title);
85 | }
86 |
87 | protected boolean hasBackButton() {
88 | return false;
89 | }
90 |
91 | protected int getActionBarCustomView() {
92 | return 0;
93 | }
94 |
95 | protected void init(Bundle savedInstanceState) {
96 |
97 | }
98 |
99 | protected void initActionBar(Toolbar actionBar) {
100 | if (actionBar == null) return;
101 |
102 | setSupportActionBar(actionBar);
103 |
104 | if (hasBackButton()) {
105 | int layoutRes = getActionBarCustomView();
106 | if (layoutRes != 0) {
107 | View view = inflateView(layoutRes);
108 | Toolbar.LayoutParams params = new Toolbar.LayoutParams(ViewGroup.LayoutParams
109 | .MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
110 | }
111 |
112 | int titleRes = getActionBarTitle();
113 |
114 | if (titleRes != 0) {
115 | actionBar.setTitle(titleRes);
116 | }
117 |
118 | actionBar.setNavigationIcon(R.drawable.actionbar_back_icon_normal);
119 | actionBar.setNavigationOnClickListener(new View.OnClickListener() {
120 | @Override
121 | public void onClick(View v) {
122 | onBackPressed();
123 | }
124 | });
125 |
126 | actionBar.setPadding(0, 0, 0, 0);
127 | } else {
128 | int titleRes = getActionBarTitle();
129 | if (titleRes != 0) {
130 | actionBar.setTitle(titleRes);
131 | }
132 |
133 | actionBar.setPadding((int) TDevice.dpToPixel(16), 0, 0, 0);
134 |
135 | }
136 | }
137 |
138 | public void setActionBarTitle(int resId) {
139 | if (resId != 0)
140 | setActionBarTitle(getString(resId));
141 | }
142 |
143 | @Override
144 | public boolean onOptionsItemSelected(MenuItem item) {
145 | switch (item.getItemId()) {
146 | case android.R.id.home:
147 | onBackPressed();
148 | break;
149 |
150 | default:
151 | break;
152 | }
153 | return super.onOptionsItemSelected(item);
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/base/BaseFragment.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.base;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.view.View;
5 |
6 |
7 | public abstract class BaseFragment extends Fragment implements View.OnClickListener {
8 | protected static final int STATE_NONE = 0;
9 | protected static final int STATE_REFRESH = 1;
10 | protected static final int STATE_LOADMORE = 2;
11 | protected int mState = STATE_NONE;
12 |
13 | @Override
14 | public void onClick(View v) {
15 |
16 | }
17 |
18 | /**
19 | * Listener the back key click event.
20 | *
21 | * @return false (default)
22 | */
23 | public boolean onBackPressed() {
24 | return false;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/base/BaseTabFragment.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.base;
2 |
3 | import tk.wlemuel.cotable.model.BlogList;
4 |
5 | public abstract class BaseTabFragment extends BaseFragment {
6 |
7 | protected int mCatalog = BlogList.CATALOG_LASTEST;
8 | private TabChangedListener mListener;
9 |
10 | public BaseTabFragment() {
11 | }
12 |
13 | public void setCatalog(int catalog) {
14 | mCatalog = catalog;
15 | }
16 |
17 | public final void addListener(TabChangedListener listener) {
18 | mListener = listener;
19 | }
20 |
21 | protected final boolean e() {
22 | return mListener.isCurrent(this);
23 | }
24 |
25 | public void f() {
26 | }
27 |
28 | public void g() {
29 | }
30 |
31 | public void h() {
32 | }
33 |
34 | public void i() {
35 | }
36 |
37 | public interface TabChangedListener {
38 |
39 | boolean isCurrent(BaseTabFragment fragment);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/cache/CacheManager.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.cache;
2 |
3 | import android.content.Context;
4 |
5 | import java.io.File;
6 | import java.io.FileInputStream;
7 | import java.io.FileNotFoundException;
8 | import java.io.FileOutputStream;
9 | import java.io.InvalidClassException;
10 | import java.io.ObjectInputStream;
11 | import java.io.ObjectOutputStream;
12 | import java.io.Serializable;
13 |
14 | /**
15 | * CacheManager
16 | *
17 | * @author Steve Lemuel
18 | * @version 0.1
19 | * @desc CacheManager
20 | * @created 2015/05/09
21 | * @updated 2015/05/09
22 | */
23 | public class CacheManager {
24 |
25 | /**
26 | * Save the object
27 | *
28 | * @param context context
29 | * @param ser serializable object
30 | * @param file cache file
31 | * @throws java.io.IOException IOException
32 | */
33 | @SuppressWarnings("JavaDoc")
34 | public static boolean saveObject(Context context, Serializable ser,
35 | String file) {
36 | FileOutputStream fos = null;
37 | ObjectOutputStream oos = null;
38 | try {
39 | fos = context.openFileOutput(file, Context.MODE_PRIVATE);
40 | oos = new ObjectOutputStream(fos);
41 | oos.writeObject(ser);
42 | oos.flush();
43 | return true;
44 | } catch (Exception e) {
45 | e.printStackTrace();
46 | return false;
47 | } finally {
48 | try {
49 | if (oos != null) oos.close();
50 | } catch (Exception e) {
51 | e.printStackTrace();
52 | }
53 | try {
54 | if (fos != null) fos.close();
55 | } catch (Exception e) {
56 | e.printStackTrace();
57 | }
58 | }
59 | }
60 |
61 | /**
62 | * Read the object
63 | *
64 | * @param context context
65 | * @param file cache file
66 | * @return serializable object
67 | * @throws java.io.IOException Exception
68 | */
69 | @SuppressWarnings("JavaDoc")
70 | public static Serializable readObject(Context context, String file) {
71 | if (!isExistDataCache(context, file))
72 | return null;
73 | FileInputStream fis = null;
74 | ObjectInputStream ois = null;
75 | try {
76 | fis = context.openFileInput(file);
77 | ois = new ObjectInputStream(fis);
78 | return (Serializable) ois.readObject();
79 | } catch (FileNotFoundException e) {
80 | e.printStackTrace();
81 | } catch (Exception e) {
82 | e.printStackTrace();
83 | // Delete the cache file if the deserialization failed.
84 | if (e instanceof InvalidClassException) {
85 | File data = context.getFileStreamPath(file);
86 | //noinspection ResultOfMethodCallIgnored
87 | data.delete();
88 | }
89 | } finally {
90 | try {
91 | if (ois != null) ois.close();
92 | } catch (Exception e) {
93 | e.printStackTrace();
94 | }
95 | try {
96 | if (fis != null) fis.close();
97 | } catch (Exception e) {
98 | e.printStackTrace();
99 | }
100 | }
101 | return null;
102 | }
103 |
104 | /**
105 | * Judge whether the cache file is readable.
106 | *
107 | * @param context context
108 | * @param cachefile cache file
109 | * @return true if the cache file is readable, false otherwise.
110 | */
111 | public static boolean isReadDataCache(Context context, String cachefile) {
112 | return readObject(context, cachefile) != null;
113 | }
114 |
115 | /**
116 | * Juget whether the cache file exists.
117 | *
118 | * @param context context
119 | * @param cachefile cache file
120 | * @return true if the cache data exists, false otherwise.
121 | */
122 | public static boolean isExistDataCache(Context context, String cachefile) {
123 | if (context == null)
124 | return false;
125 | boolean exist = false;
126 | File data = context.getFileStreamPath(cachefile);
127 | if (data.exists())
128 | exist = true;
129 | return exist;
130 | }
131 |
132 |
133 | }
134 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/core/AppConfig.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.core;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.os.Environment;
6 | import android.preference.PreferenceManager;
7 |
8 | import java.io.File;
9 | import java.io.FileInputStream;
10 | import java.io.FileOutputStream;
11 | import java.util.Properties;
12 |
13 | /**
14 | * AppConfig
15 | *
16 | * @author Steve Lemuel
17 | * @version 0.1
18 | * @desc AppConfig
19 | * @created 2015/05/08
20 | * @updated 2015/05/08
21 | */
22 | public class AppConfig {
23 |
24 | public final static String TAG = AppConfig.class.getSimpleName();
25 |
26 | public final static String APP_CONFIG = "config";
27 | public final static String APP_NAME = "Cotable";
28 | public final static String UTF8 = "utf-8";
29 | public final static int DEFAULT_PAGE_SIZE = 20;
30 |
31 | // Set the image and cache directory.
32 | public final static String DOWNLOAD_IMAGE_DIR = "image";
33 | public final static String SAVE_IMAGE_PATH = "SAVE_IMAGE_PATH";
34 | public final static String DEFAULT_IMAGE_PATH = Environment.getExternalStorageDirectory() +
35 | File.separator + APP_NAME + File.separator + DOWNLOAD_IMAGE_DIR + File.separator;
36 |
37 | public final static String CONF_LOAD_IMAGE = "CONF_LOAD_IMAGE";
38 | public final static String CONF_PAGE_SIZE = "CONF_PAGE_SIZE";
39 |
40 | // Other configurations
41 | public final static int SEARCH_ICON_SIZE_PATCH = 20;
42 | public final static String LOCAL_PATH = "file:///android_asset/";
43 |
44 | private static AppConfig appConfig;
45 | private Context mContext;
46 |
47 | public static AppConfig getAppConfig() {
48 | if (appConfig == null) appConfig = new AppConfig();
49 |
50 | return appConfig;
51 | }
52 |
53 | public static AppConfig getAppConfig(Context context) {
54 | getAppConfig().mContext = context;
55 | return appConfig;
56 | }
57 |
58 | public static SharedPreferences getSharedPreferences(Context context) {
59 | return PreferenceManager.getDefaultSharedPreferences(context);
60 | }
61 |
62 | public static boolean isLoadImage(Context context) {
63 | return getSharedPreferences(context).getBoolean(CONF_LOAD_IMAGE, true);
64 | }
65 |
66 | public static int getPageSize(Context context) {
67 | return getSharedPreferences(context).getInt(CONF_PAGE_SIZE, DEFAULT_PAGE_SIZE);
68 | }
69 |
70 |
71 | public String get(String key) {
72 | Properties props = get();
73 | return (props == null) ? null : props.getProperty(key);
74 | }
75 |
76 | public Properties get() {
77 | FileInputStream fis = null;
78 | Properties props = new Properties();
79 |
80 | File dirConf = mContext.getDir(APP_CONFIG, Context.MODE_MULTI_PROCESS);
81 | try {
82 | fis = new FileInputStream(dirConf.getPath() + File.separator + APP_CONFIG);
83 | props.load(fis);
84 | } catch (Exception e) {
85 | e.printStackTrace();
86 | } finally {
87 | try {
88 | if (fis != null) fis.close();
89 | } catch (Exception e) {
90 | e.printStackTrace();
91 | }
92 | }
93 |
94 | return props;
95 | }
96 |
97 | private void setProps(Properties props) {
98 | FileOutputStream fos = null;
99 | try {
100 | File dirConf = mContext.getDir(APP_CONFIG, Context.MODE_MULTI_PROCESS);
101 | File conf = new File(dirConf, APP_CONFIG);
102 | fos = new FileOutputStream(conf);
103 |
104 | props.store(fos, null);
105 | fos.flush();
106 | } catch (Exception e) {
107 | e.printStackTrace();
108 | } finally {
109 | try {
110 | if (fos != null) fos.close();
111 | } catch (Exception e) {
112 | e.printStackTrace();
113 | }
114 |
115 | }
116 | }
117 |
118 | public void set(Properties p) {
119 | Properties props = get();
120 | props.putAll(p);
121 | setProps(props);
122 | }
123 |
124 | public void set(String key, String value) {
125 | Properties props = get();
126 | props.put(key, value);
127 | setProps(props);
128 | }
129 |
130 | public void remove(String... keys) {
131 | Properties props = get();
132 | for (String key : keys)
133 | props.remove(key);
134 |
135 | setProps(props);
136 | }
137 |
138 | }
139 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/core/AppException.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.core;
2 |
3 | /**
4 | * AppException
5 | *
6 | * @author Steve Lemuel
7 | * @version 0.1
8 | * @desc AppException
9 | * @created 2015/05/20
10 | * @updated 2015/05/20
11 | */
12 | public class AppException {
13 |
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/core/AppManager.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.core;
2 |
3 | import android.app.Activity;
4 | import android.app.ActivityManager;
5 | import android.content.Context;
6 |
7 | import java.util.Stack;
8 |
9 | /**
10 | * AppManager
11 | *
12 | * @author Steve Lemuel
13 | * @version 0.1
14 | * @desc Manage the activities of current application.
15 | * @created 2015/05/18
16 | * @updated 2015/05/18
17 | */
18 | public class AppManager {
19 |
20 | private static Stack mActivityStack;
21 | private static AppManager mInstance;
22 |
23 | private AppManager() {
24 | }
25 |
26 |
27 | /**
28 | * Simple Singleton Design pattern.
29 | *
30 | * @return {@code AppManager}
31 | */
32 | public static AppManager getAppManager() {
33 | if (mInstance == null) mInstance = new AppManager();
34 |
35 | return mInstance;
36 | }
37 |
38 | /**
39 | * Add activity to the stack.
40 | *
41 | * @param activity activity
42 | */
43 | public void addActivity(Activity activity) {
44 | if (mActivityStack == null) mActivityStack = new Stack<>();
45 |
46 | mActivityStack.add(activity);
47 | }
48 |
49 | /**
50 | * Returns the current activity at the top of stack.
51 | *
52 | * @return Activity if the stack exists, null otherwise.
53 | */
54 | public Activity currentActivity() {
55 | if (mActivityStack == null) return null;
56 | return mActivityStack.lastElement();
57 | }
58 |
59 | /**
60 | * Finish the given activity.
61 | *
62 | * @param activity given activity.
63 | */
64 | public void finishActivity(Activity activity) {
65 | if (mActivityStack != null && activity != null) {
66 | mActivityStack.remove(activity);
67 | activity.finish();
68 | }
69 | }
70 |
71 | /**
72 | * Finish the current activity.
73 | */
74 | public void finishActivity() {
75 | finishActivity(currentActivity());
76 | }
77 |
78 | /**
79 | * Finish the activities according to the given class type.
80 | *
81 | * @param clz the class type
82 | */
83 | public void finishActivity(Class> clz) {
84 | if (mActivityStack == null) return;
85 |
86 | for (Activity activity : mActivityStack) {
87 | if (activity.getClass().equals(clz))
88 | finishActivity(activity);
89 | }
90 | }
91 |
92 | /**
93 | * Finish all the activities.
94 | */
95 | public void finishAllActivities() {
96 | if (mActivityStack == null) return;
97 |
98 | for (Activity activity : mActivityStack) {
99 | if (null != activity)
100 | finishActivity(activity);
101 | }
102 | }
103 |
104 | /**
105 | * Exit the application.
106 | *
107 | * @param context given context
108 | */
109 | public void AppExit(Context context) {
110 | try {
111 | finishAllActivities();
112 | ActivityManager activityManager = (ActivityManager) context.getSystemService(Context
113 | .ACTIVITY_SERVICE);
114 | activityManager.restartPackage(context.getPackageName());
115 | System.exit(0);
116 | } catch (Exception e) {
117 | e.printStackTrace();
118 | }
119 | }
120 |
121 |
122 | }
123 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/model/Base.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.model;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Base
7 | *
8 | * @author Steve Lemuel
9 | * @version 0.1
10 | * @desc Base
11 | * @created 2015/05/09
12 | * @updated 2015/05/09
13 | */
14 | public abstract class Base implements Serializable {
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/model/BlogDetail.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.model;
2 |
3 | import org.json.JSONObject;
4 | import org.json.JSONTokener;
5 |
6 | /**
7 | * BlogDetail
8 | *
9 | * @author Steve Lemuel
10 | * @version 0.1
11 | * @desc BlogDetail
12 | * @created 2015/05/11
13 | * @updated 2015/05/11
14 | */
15 | public class BlogDetail extends Entity {
16 |
17 | private final static String TAG_BODY = "string";
18 |
19 | private String postId;
20 |
21 | private String body;
22 |
23 | public BlogDetail(String postId, String body) {
24 | setPostId(postId);
25 | setBody(body);
26 | }
27 |
28 | public static BlogDetail parse(String data) {
29 | BlogDetail blog = new BlogDetail("", "Hello, I'm Lemuel.
");
30 |
31 |
32 | if (data != null && !data.equals("")) {
33 |
34 | try {
35 | JSONTokener jsonParser = new JSONTokener(data);
36 |
37 | JSONObject content = (JSONObject) jsonParser.nextValue();
38 | blog.setBody(content.getString("data"));
39 |
40 | } catch (Exception e) {
41 | e.printStackTrace();
42 | }
43 | }
44 |
45 | return blog;
46 |
47 | }
48 |
49 | public String getPostId() {
50 | return postId;
51 | }
52 |
53 | public void setPostId(String postId) {
54 | this.postId = postId;
55 | }
56 |
57 | public String getBody() {
58 | return body;
59 | }
60 |
61 | public void setBody(String body) {
62 | this.body = body;
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/model/BlogList.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.model;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * BlogList
8 | *
9 | * @author Steve Lemuel
10 | * @version 0.1
11 | * @desc BlogList
12 | * @created 2015/05/09
13 | * @updated 2015/05/09
14 | */
15 | public class BlogList extends Entity implements ListEntity {
16 |
17 | public static final int CATALOG_LASTEST = 1;
18 | public static final int CATALOG_RECOMMEND = 2;
19 |
20 | public static final String TYPE_LASTEST = "BLOG_LASTEST";
21 | public static final String TYPE_RECOMMEND = "BLOG_RECOMMEND";
22 |
23 | private List bloglist = new ArrayList<>();
24 | private int pageSize;
25 | private int blogCount;
26 |
27 | public static BlogList parse(String data) {
28 | BlogList bloglist = new BlogList();
29 | bloglist.getBloglist().addAll(Blog.parse(data));
30 | return bloglist;
31 | }
32 |
33 | public int getPageSize() {
34 | return pageSize;
35 | }
36 |
37 | public int getBlogCount() {
38 | return blogCount;
39 | }
40 |
41 | public List getBloglist() {
42 | return bloglist;
43 | }
44 |
45 | @Override
46 | public List> getList() {
47 | return bloglist;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/model/DrawerMenu.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.model;
2 |
3 |
4 | public class DrawerMenu extends Entity {
5 | private String icon;
6 | private String text;
7 |
8 |
9 | public String getIcon() {
10 | return icon;
11 | }
12 |
13 | public void setIcon(String icon) {
14 | this.icon = icon;
15 | }
16 |
17 | public String getText() {
18 | return text;
19 | }
20 |
21 | public void setText(String text) {
22 | this.text = text;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/model/Entity.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.model;
2 |
3 | /**
4 | * Entity
5 | *
6 | * @author Steve Lemuel
7 | * @version 0.1
8 | * @desc Entity
9 | * @created 2015/05/09
10 | * @updated 2015/05/09
11 | */
12 | public abstract class Entity extends Base {
13 |
14 | protected int id;
15 | protected String cacheKey;
16 |
17 | public int getId() {
18 | return id;
19 | }
20 |
21 | public void setId(int id) {
22 | this.id = id;
23 | }
24 |
25 | public String getCacheKey() {
26 | return cacheKey;
27 | }
28 |
29 | public void setCacheKey(String cacheKey) {
30 | this.cacheKey = cacheKey;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/model/ListEntity.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.model;
2 |
3 | import java.io.Serializable;
4 | import java.util.List;
5 |
6 | /**
7 | * ListEntity
8 | *
9 | * @author Steve Lemuel
10 | * @version 0.1
11 | * @desc ListEntity
12 | * @created 2015/05/09
13 | * @updated 2015/05/09
14 | */
15 | public interface ListEntity extends Serializable {
16 |
17 | List> getList();
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/model/News.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.model;
2 |
3 | /**
4 | * News
5 | *
6 | * @author Steve Lemuel
7 | * @version 0.1
8 | * @desc News
9 | * @created 2015/05/09
10 | * @updated 2015/05/09
11 | */
12 | public class News extends Base{
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/model/SimpleBackPage.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.model;
2 |
3 | import tk.wlemuel.cotable.R;
4 | import tk.wlemuel.cotable.activity.blog.fragment.BlogDetailFragment;
5 | import tk.wlemuel.cotable.activity.settings.fragment.AboutFragment;
6 | import tk.wlemuel.cotable.activity.settings.fragment.SettingFragment;
7 |
8 | /**
9 | * SimpleBackPage
10 | *
11 | * @author Steve Lemuel
12 | * @version 0.1
13 | * @desc SimpleBackPage
14 | * @created 2015/05/12
15 | * @updated 2015/05/12
16 | */
17 | public enum SimpleBackPage {
18 |
19 | SETTING(0, R.string.actionbar_title_setting, SettingFragment.class),
20 | ABOUT(1, R.string.actionbar_title_about, AboutFragment.class),
21 | DETAILS(2, R.string.actionbar_title_blogdetail, BlogDetailFragment.class);
22 |
23 | private int title;
24 | private Class> clz;
25 | private int value;
26 |
27 | SimpleBackPage(int value, int title, Class> clz) {
28 | this.title = title;
29 | this.clz = clz;
30 | this.value = value;
31 | }
32 |
33 | public static SimpleBackPage getPageByValue(int value) {
34 | for (SimpleBackPage p : values()) {
35 | if (p.getValue() == value) {
36 | return p;
37 | }
38 | }
39 |
40 | return null;
41 | }
42 |
43 | public int getTitle() {
44 | return title;
45 | }
46 |
47 | public void setTitle(int title) {
48 | this.title = title;
49 | }
50 |
51 | public Class> getClz() {
52 | return clz;
53 | }
54 |
55 | public void setClz(Class> clz) {
56 | this.clz = clz;
57 | }
58 |
59 | public int getValue() {
60 | return value;
61 | }
62 |
63 | public void setValue(int value) {
64 | this.value = value;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/ui/customWidget/CircleImageView.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.ui.customWidget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.PaintFlagsDrawFilter;
9 | import android.graphics.PorterDuff;
10 | import android.graphics.PorterDuffXfermode;
11 | import android.graphics.Rect;
12 | import android.graphics.RectF;
13 | import android.util.AttributeSet;
14 | import android.view.View;
15 |
16 | /**
17 | * Created by stevelemuel on 4/12/15.
18 | */
19 | public class CircleImageView extends View {
20 | private Bitmap bitmap;
21 | private Rect bitmapRect = new Rect();
22 | private PaintFlagsDrawFilter pdf = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
23 | private Paint paint = new Paint();
24 |
25 | {
26 | paint.setStyle(Paint.Style.STROKE);
27 | paint.setFlags(Paint.ANTI_ALIAS_FLAG);
28 | paint.setAntiAlias(true);// 设置画笔的锯齿效果。 true是去除,大家一看效果就明白了
29 | }
30 |
31 | private Bitmap mDstB = null;
32 | private PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY);
33 |
34 | public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
35 | super(context, attrs, defStyle);
36 | init();
37 | }
38 |
39 | public CircleImageView(Context context, AttributeSet attrs) {
40 | super(context, attrs);
41 | init();
42 | }
43 |
44 | public CircleImageView(Context context) {
45 | super(context);
46 | init();
47 | }
48 |
49 | private void init() {
50 | try {
51 | if (android.os.Build.VERSION.SDK_INT >= 11) {
52 | setLayerType(LAYER_TYPE_SOFTWARE, null);
53 | }
54 | } catch (Exception e) {
55 | e.printStackTrace();
56 | }
57 | }
58 |
59 | public void setImageBitmap(Bitmap bitmap) {
60 | this.bitmap = bitmap;
61 | }
62 |
63 | private Bitmap makeDst(int w, int h) {
64 | Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
65 | Canvas c = new Canvas(bm);
66 | Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
67 | p.setColor(Color.parseColor("#ffffffff"));
68 | c.drawOval(new RectF(0, 0, w, h), p);
69 | return bm;
70 | }
71 |
72 | @Override
73 | protected void onDraw(Canvas canvas) {
74 |
75 | if (null == bitmap) {
76 | return;
77 | }
78 | if (null == mDstB) {
79 | mDstB = makeDst(getWidth(), getHeight());
80 | }
81 |
82 | bitmapRect.set(0, 0, getWidth(), getHeight());
83 | canvas.save();
84 | canvas.setDrawFilter(pdf);
85 | canvas.drawBitmap(mDstB, 0, 0, paint);
86 | paint.setXfermode(xfermode);
87 | canvas.drawBitmap(bitmap, null, bitmapRect, paint);
88 | paint.setXfermode(null);
89 | canvas.restore();
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/ui/decorator/DividerItemDecoration.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.ui.decorator;
2 |
3 | import android.content.Context;
4 | import android.content.res.TypedArray;
5 | import android.graphics.Canvas;
6 | import android.graphics.Rect;
7 | import android.graphics.drawable.Drawable;
8 | import android.support.v4.view.ViewCompat;
9 | import android.support.v7.widget.LinearLayoutManager;
10 | import android.support.v7.widget.RecyclerView;
11 | import android.view.View;
12 |
13 | /**
14 | * DividerItemDecoration
15 | *
16 | * @author Steve Lemuel
17 | * @version 0.1
18 | * @desc DividerItemDecoration
19 | * @created 2015/05/10
20 | * @updated 2015/05/10
21 | */
22 | public class DividerItemDecoration extends RecyclerView.ItemDecoration {
23 |
24 | public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
25 | public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
26 | private static final int[] ATTRS = new int[]{
27 | android.R.attr.listDivider
28 | };
29 | private Drawable mDivider;
30 |
31 | private int mOrientation;
32 |
33 | public DividerItemDecoration(Context context, int orientation) {
34 | final TypedArray a = context.obtainStyledAttributes(ATTRS);
35 | mDivider = a.getDrawable(0);
36 | a.recycle();
37 | setOrientation(orientation);
38 | }
39 |
40 | public void setOrientation(int orientation) {
41 | if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
42 | throw new IllegalArgumentException("invalid orientation");
43 | }
44 | mOrientation = orientation;
45 | }
46 |
47 | @Override
48 | public void onDraw(Canvas c, RecyclerView parent) {
49 | if (mOrientation == VERTICAL_LIST) {
50 | drawVertical(c, parent);
51 | } else {
52 | drawHorizontal(c, parent);
53 | }
54 | }
55 |
56 | public void drawVertical(Canvas c, RecyclerView parent) {
57 | final int left = parent.getPaddingLeft();
58 | final int right = parent.getWidth() - parent.getPaddingRight();
59 |
60 | final int childCount = parent.getChildCount();
61 | for (int i = 0; i < childCount; i++) {
62 | final View child = parent.getChildAt(i);
63 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
64 | .getLayoutParams();
65 | final int top = child.getBottom() + params.bottomMargin +
66 | Math.round(ViewCompat.getTranslationY(child));
67 | final int bottom = top + mDivider.getIntrinsicHeight();
68 | mDivider.setBounds(left, top, right, bottom);
69 | mDivider.draw(c);
70 | }
71 | }
72 |
73 | public void drawHorizontal(Canvas c, RecyclerView parent) {
74 | final int top = parent.getPaddingTop();
75 | final int bottom = parent.getHeight() - parent.getPaddingBottom();
76 |
77 | final int childCount = parent.getChildCount();
78 | for (int i = 0; i < childCount; i++) {
79 | final View child = parent.getChildAt(i);
80 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
81 | .getLayoutParams();
82 | final int left = child.getRight() + params.rightMargin +
83 | Math.round(ViewCompat.getTranslationX(child));
84 | final int right = left + mDivider.getIntrinsicHeight();
85 | mDivider.setBounds(left, top, right, bottom);
86 | mDivider.draw(c);
87 | }
88 | }
89 |
90 | @Override
91 | public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
92 | if (mOrientation == VERTICAL_LIST) {
93 | outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
94 | } else {
95 | outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/ui/dialog/DialogControl.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.ui.dialog;
2 |
3 | /**
4 | * Created by stevelemuel on 4/17/15.
5 | */
6 | public interface DialogControl {
7 |
8 | public abstract void hideWaitDialog();
9 |
10 | public abstract WaitDialog showWaitDialog();
11 |
12 | public abstract WaitDialog showWaitDialog(int resId);
13 |
14 | public abstract WaitDialog showWaitDialog(String text);
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/ui/dialog/WaitDialog.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.ui.dialog;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 |
6 | /**
7 | * Created by stevelemuel on 4/17/15.
8 | */
9 | public class WaitDialog extends Dialog{
10 |
11 | public WaitDialog(Context context){
12 | super(context);
13 |
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/ui/drawer/DrawerMenuAdapter.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.ui.drawer;
2 |
3 | import android.content.Context;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.BaseAdapter;
8 |
9 | import java.util.List;
10 |
11 | import tk.wlemuel.cotable.R;
12 | import tk.wlemuel.cotable.model.DrawerMenu;
13 |
14 | /**
15 | * DrawerMenuAdapter
16 | *
17 | * @author Steve Lemuel
18 | * @version 0.1
19 | * @desc DrawerMenuAdapter
20 | * @created 2015/05/14
21 | * @updated 2015/05/14
22 | */
23 | public class DrawerMenuAdapter extends BaseAdapter {
24 |
25 | private LayoutInflater mInflater;
26 | private List mItemsData;
27 |
28 | public DrawerMenuAdapter(Context context, List listItemData) {
29 | mInflater = LayoutInflater.from(context);
30 | mItemsData = listItemData;
31 |
32 | }
33 |
34 | @Override
35 | public Object getItem(int position) {
36 | return mItemsData.get(position);
37 | }
38 |
39 | @Override
40 | public long getItemId(int position) {
41 | return position;
42 | }
43 |
44 | @Override
45 | public View getView(int position, View convertView, ViewGroup parent) {
46 | DrawerMenuHolder holder;
47 |
48 | if (convertView == null) {
49 | convertView = mInflater.inflate(R.layout.activity_main_drawer_left_list_item, null);
50 | holder = new DrawerMenuHolder(convertView);
51 | convertView.setTag(holder);
52 | } else {
53 | holder = (DrawerMenuHolder) convertView.getTag();
54 | }
55 |
56 | DrawerMenu item = mItemsData.get(position);
57 | holder.getIconTextView().setText(item.getIcon());
58 | holder.getTextView().setText(item.getText());
59 |
60 | return convertView;
61 | }
62 |
63 | @Override
64 | public int getCount() {
65 | return mItemsData.size();
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/ui/drawer/DrawerMenuHolder.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.ui.drawer;
2 |
3 | import android.view.View;
4 | import android.widget.IconTextView;
5 | import android.widget.TextView;
6 |
7 | import tk.wlemuel.cotable.R;
8 |
9 |
10 | public class DrawerMenuHolder {
11 | private IconTextView mIconTextView;
12 | private TextView mTextView;
13 |
14 | public DrawerMenuHolder(View view) {
15 | mIconTextView = (IconTextView) view.findViewById(R.id.drawer_left_list_item_icon);
16 | mTextView = (TextView) view.findViewById(R.id.drawer_left_list_item_text);
17 | }
18 |
19 | public TextView getTextView() {
20 | return mTextView;
21 | }
22 |
23 | public IconTextView getIconTextView() {
24 | return mIconTextView;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/ui/empty/EmptyLayout.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.ui.empty;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 | import android.view.animation.Animation;
7 | import android.view.animation.AnimationUtils;
8 | import android.widget.ImageView;
9 | import android.widget.LinearLayout;
10 | import android.widget.ProgressBar;
11 | import android.widget.RelativeLayout;
12 | import android.widget.TextView;
13 |
14 | import tk.wlemuel.cotable.R;
15 | import tk.wlemuel.cotable.utils.TDevice;
16 |
17 |
18 | public class EmptyLayout extends LinearLayout implements
19 | View.OnClickListener {
20 |
21 | public static final int HIDE_LAYOUT = 4;
22 | public static final int NETWORK_ERROR = 1;
23 | public static final int NETWORK_LOADING = 2;
24 | public static final int NODATA = 3;
25 | public static final int NODATA_ENABLE_CLICK = 5;
26 | private ProgressBar animProgress;
27 | private boolean clickEnable = true;
28 | private Context context;
29 | private ImageView img;
30 | private OnClickListener listener;
31 | private int mErrorState;
32 | private RelativeLayout mLayout;
33 | private String strNoDataContent = "";
34 | private TextView mTv;
35 | private Animation mAnim;
36 |
37 | public EmptyLayout(Context context) {
38 | super(context);
39 | this.context = context;
40 | init();
41 | }
42 |
43 | public EmptyLayout(Context context, AttributeSet attrs) {
44 | super(context, attrs);
45 | this.context = context;
46 | init();
47 | }
48 |
49 | /**
50 | * init the view.
51 | */
52 | private void init() {
53 | View view = View.inflate(context, R.layout.view_error_layout, null);
54 | img = (ImageView) view.findViewById(R.id.error_layout_img);
55 | mTv = (TextView) view.findViewById(R.id.error_layout_tv);
56 | mLayout = (RelativeLayout) view.findViewById(R.id.error_layout_main);
57 | animProgress = (ProgressBar) view.findViewById(R.id.error_layout_animProgress);
58 | mAnim = AnimationUtils.loadAnimation(context, R.anim.progressbar_loading);
59 | setBackgroundColor(-1);
60 | setOnClickListener(this);
61 | img.setOnClickListener(new OnClickListener() {
62 |
63 | @Override
64 | public void onClick(View v) {
65 | if (clickEnable) {
66 | //setErrorType(NETWORK_LOADING);
67 | if (listener != null)
68 | listener.onClick(v);
69 | }
70 | }
71 | });
72 |
73 | addView(view);
74 | }
75 |
76 | public void dismiss() {
77 | mErrorState = HIDE_LAYOUT;
78 | setVisibility(View.GONE);
79 | }
80 |
81 | public int getErrorState() {
82 | return mErrorState;
83 | }
84 |
85 | public boolean isLoadError() {
86 | return mErrorState == NETWORK_ERROR;
87 | }
88 |
89 | public boolean isLoading() {
90 | return mErrorState == NETWORK_LOADING;
91 | }
92 |
93 | @Override
94 | public void onClick(View v) {
95 | if (clickEnable) {
96 | //setErrorType(NETWORK_LOADING);
97 | if (listener != null)
98 | listener.onClick(v);
99 | }
100 | }
101 |
102 | @Override
103 | protected void onAttachedToWindow() {
104 | super.onAttachedToWindow();
105 | }
106 |
107 | @Override
108 | protected void onDetachedFromWindow() {
109 | super.onDetachedFromWindow();
110 | }
111 |
112 | public void setErrorMessage(String msg) {
113 | mTv.setText(msg);
114 | }
115 |
116 | public void setErrorMessage(int msg) {
117 | if (msg != 0) mTv.setText(msg);
118 | }
119 |
120 | public void setErrorType(int i) {
121 | setVisibility(View.VISIBLE);
122 | switch (i) {
123 | case NETWORK_ERROR:
124 | mErrorState = NETWORK_ERROR;
125 | if (TDevice.hasInternet()) {
126 | mTv.setText(R.string.empty_view_click_to_refresh);
127 | img.setBackgroundResource(R.drawable.pagefailed_bg);
128 | } else {
129 | mTv.setText(R.string.empty_view_network_error);
130 | img.setBackgroundResource(R.drawable.page_icon_network);
131 | }
132 | img.setVisibility(View.VISIBLE);
133 | animProgress.setVisibility(View.GONE);
134 | animProgress.clearAnimation();
135 | clickEnable = true;
136 | break;
137 | case NETWORK_LOADING:
138 | mErrorState = NETWORK_LOADING;
139 | animProgress.setVisibility(View.VISIBLE);
140 | animProgress.clearAnimation();
141 | animProgress.startAnimation(mAnim);
142 | img.setVisibility(View.GONE);
143 | mTv.setText(R.string.loading);
144 | clickEnable = false;
145 | break;
146 | case NODATA:
147 | mErrorState = NODATA;
148 | img.setVisibility(View.VISIBLE);
149 | animProgress.setVisibility(View.GONE);
150 | animProgress.clearAnimation();
151 | setTvNoDataContent();
152 | clickEnable = false;
153 | break;
154 | case HIDE_LAYOUT:
155 | setVisibility(View.GONE);
156 | animProgress.clearAnimation();
157 | break;
158 | case NODATA_ENABLE_CLICK:
159 | mErrorState = NODATA_ENABLE_CLICK;
160 | img.setVisibility(View.VISIBLE);
161 | animProgress.setVisibility(View.GONE);
162 | animProgress.clearAnimation();
163 | setTvNoDataContent();
164 | clickEnable = true;
165 | break;
166 | default:
167 | break;
168 | }
169 | }
170 |
171 | public void setNoDataContent(String noDataContent) {
172 | strNoDataContent = noDataContent;
173 | }
174 |
175 | public void setOnLayoutClickListener(OnClickListener listener) {
176 | this.listener = listener;
177 | }
178 |
179 | public void setTvNoDataContent() {
180 | if (!strNoDataContent.equals(""))
181 | mTv.setText(strNoDataContent);
182 | else
183 | mTv.setText(R.string.empty_view_no_data);
184 | }
185 |
186 | @Override
187 | public void setVisibility(int visibility) {
188 | if (visibility == View.GONE)
189 | mErrorState = HIDE_LAYOUT;
190 | super.setVisibility(visibility);
191 | }
192 |
193 | public String getMessage() {
194 | if (mTv != null) {
195 | return mTv.getText().toString();
196 | }
197 | return "";
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/ui/pagertab/SlidingTabPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.ui.pagertab;
2 |
3 | import android.content.Context;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentPagerAdapter;
6 | import android.support.v4.view.ViewPager;
7 |
8 | import tk.wlemuel.cotable.base.BaseTabFragment;
9 | import tk.wlemuel.cotable.base.BaseTabFragment.TabChangedListener;
10 | import tk.wlemuel.cotable.ui.pagertab.PagerSlidingTabStrip.OnTabClickListener;
11 |
12 | /**
13 | * SlidingTabPagerAdapter
14 | *
15 | * @author Steve Lemuel
16 | * @version 0.1
17 | * @desc SlidingTabPagerAdapter
18 | * @created 2015/05/10
19 | * @updated 2015/05/10
20 | */
21 | public abstract class SlidingTabPagerAdapter extends FragmentPagerAdapter
22 | implements TabChangedListener, OnTabClickListener {
23 |
24 | protected final Context context;
25 | protected final BaseTabFragment[] fragments;
26 | private final ViewPager pager;
27 | private int lastPostion;
28 |
29 | public SlidingTabPagerAdapter(FragmentManager mgr, int i, Context context,
30 | ViewPager vp) {
31 | super(mgr);
32 | lastPostion = 0;
33 | fragments = new BaseTabFragment[i];
34 | this.context = context;
35 | pager = vp;
36 | lastPostion = 0;
37 | }
38 |
39 | /**
40 | * Get the fragment according to the position.
41 | *
42 | * @param i position
43 | * @return BaseTabFragment
44 | */
45 | private BaseTabFragment getFragmentByPosition(int i) {
46 | BaseTabFragment fragment = null;
47 | if (i >= 0 && i < fragments.length)
48 | fragment = fragments[i];
49 | return fragment;
50 | }
51 |
52 | private void onLeave(int i) {
53 | BaseTabFragment fragment = getFragmentByPosition(lastPostion);
54 | lastPostion = i;
55 | if (fragment != null)
56 | fragment.g();
57 | }
58 |
59 | public abstract int getCacheCount();
60 |
61 | @Override
62 | public abstract int getCount();
63 |
64 | @Override
65 | public BaseTabFragment getItem(int i) {
66 | return fragments[i];
67 | }
68 |
69 | @Override
70 | public abstract CharSequence getPageTitle(int i);
71 |
72 | public boolean isCurrent(BaseTabFragment fragment) {
73 | boolean flag = false;
74 | int i = pager.getCurrentItem();
75 | int j = 0;
76 | do {
77 | label0:
78 | {
79 | if (j < fragments.length) {
80 | if (fragment != fragments[j] || j != i)
81 | break label0;
82 | flag = true;
83 | }
84 | return flag;
85 | }
86 | j++;
87 | } while (true);
88 | }
89 |
90 | public void onPageScrolled(int i) {
91 | BaseTabFragment fragment = getFragmentByPosition(i);
92 | if (fragment != null) {
93 | fragment.h();
94 | onLeave(i);
95 | }
96 | }
97 |
98 | public void onPageSelected(int i) {
99 | BaseTabFragment fragment = getFragmentByPosition(i);
100 | if (fragment != null) {
101 | fragment.f();
102 | onLeave(i);
103 | }
104 | }
105 |
106 | @Override
107 | public void onTabClicked(int i) {
108 | BaseTabFragment fragment = getFragmentByPosition(i);
109 | if (fragment != null)
110 | fragment.i();
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/ui/pagertab/q.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.ui.pagertab;
2 |
3 | import java.io.Serializable;
4 | import java.util.ArrayList;
5 | import java.util.Iterator;
6 | import java.util.List;
7 |
8 | /**
9 | * q
10 | *
11 | * @author Steve Lemuel
12 | * @version 0.1
13 | * @desc q
14 | * @created 2015/05/10
15 | * @updated 2015/05/10
16 | */
17 | public final class q implements Serializable {
18 |
19 | private static final long serialVersionUID = 0xe2d57122f51e480bL;
20 | private final int a;
21 | private int b;
22 | private boolean c;
23 | private int d;
24 | private List e;
25 |
26 | public q(int i) {
27 | a = i;
28 | d = -1;
29 | }
30 |
31 | public q(q q1) {
32 | a = q1.a;
33 | b = q1.b;
34 | c = q1.c;
35 | d = q1.d;
36 | }
37 |
38 | public final int a() {
39 | return a;
40 | }
41 |
42 | final void a(int i) {
43 | b = i;
44 | }
45 |
46 | final void a(q q1) {
47 | if (e == null)
48 | e = new ArrayList();
49 | e.add(q1);
50 | q1.d = a;
51 | }
52 |
53 | final void a(boolean flag) {
54 | c = flag;
55 | }
56 |
57 | public final int b() {
58 | return b;
59 | }
60 |
61 | public final boolean c() {
62 | return b <= 0 && c;
63 | }
64 |
65 | final void d() {
66 | if (e != null && e.size() > 0) {
67 | b = 0;
68 | c = false;
69 | Iterator iterator = e.iterator();
70 | while (iterator.hasNext()) {
71 | q q1 = (q) iterator.next();
72 | b = b + q1.b;
73 | c = c | q1.c;
74 | }
75 | }
76 | }
77 |
78 | final int e() {
79 | return d;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/ui/pagertab/r.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.ui.pagertab;
2 |
3 | import android.util.SparseArray;
4 | import android.view.View;
5 | import android.widget.TextView;
6 |
7 | import tk.wlemuel.cotable.utils.ViewUtils;
8 |
9 | /**
10 | * r
11 | *
12 | * @author Steve Lemuel
13 | * @version 0.1
14 | * @desc r
15 | * @created 2015/05/10
16 | * @updated 2015/05/10
17 | */
18 | public final class r {
19 |
20 | public r() {
21 | // a(a);
22 | }
23 |
24 | static final void a(SparseArray sparsearray) {
25 | sparsearray.put(0, new q(0));
26 | q q1 = new q(1);
27 | q q2 = new q(4);
28 | q q3 = new q(5);
29 | q q4 = new q(11);
30 | q q5 = new q(7);
31 | q q6 = new q(8);
32 | q q7 = new q(10);
33 | q q8 = new q(12);
34 | q q9 = new q(13);
35 | q q10 = new q(14);
36 | sparsearray.put(1, q1);
37 | sparsearray.put(4, q2);
38 | sparsearray.put(5, q3);
39 | sparsearray.put(11, q4);
40 | sparsearray.put(12, q8);
41 | sparsearray.put(7, q5);
42 | sparsearray.put(8, q6);
43 | sparsearray.put(10, q7);
44 | sparsearray.put(13, q9);
45 | sparsearray.put(14, q10);
46 | q1.a(q2);
47 | q1.a(q3);
48 | q1.a(q4);
49 | q1.a(q8);
50 | q1.a(q10);
51 | q4.a(q5);
52 | sparsearray.put(2, new q(2));
53 | q q11 = new q(3);
54 | sparsearray.put(3, q11);
55 | q11.a(q9);
56 | q q12 = new q(6);
57 | sparsearray.put(6, q12);
58 | q11.a(q12);
59 | }
60 |
61 | public static void a(q q1, TextView tv, View view) {
62 | if (q1 != null && tv != null && view != null) {
63 | int j = q1.b();
64 | boolean flag = q1.c();
65 | tv.setVisibility(j > 0 ? View.VISIBLE : View.GONE);
66 | view.setVisibility(flag ? View.VISIBLE : View.GONE);
67 | if (j > 0)
68 | tv.setText(String.valueOf(Math.min(99, j)));
69 | } else {
70 | ViewUtils.a(tv, View.GONE);
71 | ViewUtils.a(view, View.GONE);
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/ui/widget/FixedRecyclerView.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.ui.widget;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.os.Build;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.util.AttributeSet;
8 |
9 | /**
10 | * FixedRecycleView
11 | *
12 | * @author Steve Lemuel
13 | * @version 0.1
14 | * @desc FixedRecycleView
15 | * @created 2015/05/11
16 | * @updated 2015/05/11
17 | */
18 | public class FixedRecyclerView extends RecyclerView {
19 | public FixedRecyclerView(Context context) {
20 | super(context);
21 |
22 | }
23 |
24 | public FixedRecyclerView(Context context, AttributeSet attrs) {
25 | super(context, attrs);
26 | }
27 |
28 | public FixedRecyclerView(Context context, AttributeSet attrs, int defStyle) {
29 | super(context, attrs, defStyle);
30 | }
31 |
32 | @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
33 | @Override
34 | public boolean canScrollVertically(int direction) {
35 | // check if scrolling up
36 | if (direction < 1) {
37 | boolean original = super.canScrollVertically(direction);
38 | return !original && getChildAt(0) != null && getChildAt(0).getTop() < 0 || original;
39 | }
40 | return super.canScrollVertically(direction);
41 |
42 | }
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/utils/CircleBitmapDisplayer.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.utils;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.Canvas;
5 | import android.graphics.Paint;
6 | import android.graphics.PorterDuff;
7 | import android.graphics.PorterDuffXfermode;
8 | import android.graphics.Rect;
9 |
10 | import com.nostra13.universalimageloader.core.assist.LoadedFrom;
11 | import com.nostra13.universalimageloader.core.display.BitmapDisplayer;
12 | import com.nostra13.universalimageloader.core.imageaware.ImageAware;
13 |
14 | /**
15 | * CircleBitmapDisplayer
16 | *
17 | * @author Steve Lemuel
18 | * @version 0.1
19 | * @desc CircleBitmapDisplayer
20 | * @created 2015/05/14
21 | * @updated 2015/05/14
22 | */
23 | public class CircleBitmapDisplayer implements BitmapDisplayer {
24 |
25 | private float borderWidth = 0;
26 | private int borderColor;
27 |
28 | public CircleBitmapDisplayer() {
29 | super();
30 | }
31 |
32 | public CircleBitmapDisplayer(int borderColor, int borderWidth) {
33 | super();
34 | this.borderColor = borderColor;
35 | this.borderWidth = borderWidth;
36 | }
37 |
38 | @Override
39 | public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) {
40 | Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_4444);
41 |
42 | Canvas canvas = new Canvas(output);
43 |
44 | final int color = 0xff424242;
45 | final Paint paint = new Paint();
46 | final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
47 |
48 | paint.setAntiAlias(true);
49 | canvas.drawARGB(0, 0, 0, 0);
50 | paint.setColor(color);
51 |
52 | //--CROP THE IMAGE
53 | canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, bitmap.getWidth() / 2 - 1, paint);
54 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
55 | canvas.drawBitmap(bitmap, rect, rect, paint);
56 |
57 | //--ADD BORDER IF NEEDED
58 | if (this.borderWidth > 0) {
59 | final Paint paint2 = new Paint();
60 | paint2.setAntiAlias(true);
61 | paint2.setColor(this.borderColor);
62 | paint2.setStrokeWidth(this.borderWidth);
63 | paint2.setStyle(Paint.Style.STROKE);
64 | canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, (float) (bitmap.getWidth() / 2 - Math.ceil(this.borderWidth / 2)), paint2);
65 | }
66 | imageAware.setImageBitmap(output);
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/utils/CyptoUtils.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.utils;
2 |
3 | import java.security.Key;
4 | import java.security.spec.AlgorithmParameterSpec;
5 |
6 | import javax.crypto.Cipher;
7 | import javax.crypto.SecretKeyFactory;
8 | import javax.crypto.spec.DESKeySpec;
9 | import javax.crypto.spec.IvParameterSpec;
10 |
11 | /**
12 | * Utils for encryption and decryption.
13 | *
14 | * @author Winter Lau
15 | * @updated Steve Lemuel
16 | * @created 2011-12-26
17 | */
18 | public class CyptoUtils {
19 |
20 | public static final String ALGORITHM_DES = "DES/CBC/PKCS5Padding";
21 |
22 | /**
23 | * DES Algorithm,encryption
24 | *
25 | * @param data the string needs to be encrypted.
26 | * @param key secretKey, longer than 8 bytes.
27 | * @return the encrypted data.
28 | */
29 | public static String encode(String key, String data) {
30 | if (data == null)
31 | return null;
32 | try {
33 | DESKeySpec dks = new DESKeySpec(key.getBytes());
34 | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
35 | // The secretkey ought to longer than 8 bytes.
36 | Key secretKey = keyFactory.generateSecret(dks);
37 | Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
38 | // IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
39 | AlgorithmParameterSpec paramSpec;
40 | paramSpec = new IvParameterSpec("12345678".getBytes());
41 | cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
42 | byte[] bytes = cipher.doFinal(data.getBytes());
43 | return byte2hex(bytes);
44 | } catch (Exception e) {
45 | e.printStackTrace();
46 | return data;
47 | }
48 | }
49 |
50 | /**
51 | * DES Algorithm,decryption
52 | *
53 | * @param data the string needs to be decrypted.
54 | * @param key secretKey, longer than 8 bytes.
55 | * @return the decrypted data.
56 | */
57 | public static String decode(String key, String data) {
58 | if (data == null)
59 | return null;
60 | try {
61 | DESKeySpec dks = new DESKeySpec(key.getBytes());
62 | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
63 | // The secretkey ought to longer than 8 bytes.
64 | Key secretKey = keyFactory.generateSecret(dks);
65 | Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
66 | // IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
67 | AlgorithmParameterSpec paramSpec;
68 | paramSpec = new IvParameterSpec("12345678".getBytes());
69 | cipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec);
70 | return new String(cipher.doFinal(hex2byte(data.getBytes())));
71 | } catch (Exception e) {
72 | e.printStackTrace();
73 | return data;
74 | }
75 | }
76 |
77 | /**
78 | * Convert the binary to String
79 | *
80 | * @param b the byte array.
81 | * @return {@code String}
82 | */
83 | private static String byte2hex(byte[] b) {
84 | StringBuilder hs = new StringBuilder();
85 | String stmp;
86 | for (int n = 0; b != null && n < b.length; n++) {
87 | stmp = Integer.toHexString(b[n] & 0XFF);
88 | if (stmp.length() == 1)
89 | hs.append('0');
90 | hs.append(stmp);
91 | }
92 | return hs.toString().toUpperCase();
93 | }
94 |
95 | // TODO Don't understand this method.
96 | private static byte[] hex2byte(byte[] b) {
97 | if ((b.length % 2) != 0)
98 | throw new IllegalArgumentException();
99 | byte[] b2 = new byte[b.length / 2];
100 | for (int n = 0; n < b.length; n += 2) {
101 | String item = new String(b, n, 2);
102 | b2[n / 2] = (byte) Integer.parseInt(item, 16);
103 | }
104 | return b2;
105 | }
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/utils/HtmlUtils.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.utils;
2 |
3 | /**
4 | * HtmlUtils
5 | *
6 | * @author Steve Lemuel
7 | * @version 0.1
8 | * @desc HtmlUtils
9 | * @created 2015/05/09
10 | * @updated 2015/05/09
11 | */
12 | public class HtmlUtils {
13 |
14 | private static final String LESS_THEN = "<";
15 | private static final String GREAT_THEN = ">";
16 | private static final String AND = "&";
17 | private static final String QUOTE = """;
18 |
19 | private static final String REAL_LESS_THEN = "<";
20 | private static final String REAL_GREAT_THEN = ">";
21 | private static final String REAL_AND = "&";
22 | private static final String REAL_QUOTE = "\"";
23 |
24 | public static String filter(String org) {
25 | if (org == null || org == "") return "";
26 | org = org.replace(LESS_THEN, REAL_LESS_THEN);
27 | org = org.replace(GREAT_THEN, REAL_GREAT_THEN);
28 | org = org.replace(AND, REAL_AND);
29 | org = org.replace(QUOTE, REAL_QUOTE);
30 |
31 | return org;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/utils/OnWebViewImageListener.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.utils;
2 |
3 | /**
4 | * OnWebViewImageListener
5 | *
6 | * @author Steve Lemuel
7 | * @version 0.1
8 | * @desc OnWebViewImageListener
9 | * @created 2015/05/14
10 | * @updated 2015/05/14
11 | */
12 | public interface OnWebViewImageListener {
13 |
14 | void onImageClick(String bigImageUrl);
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/utils/TLog.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.utils;
2 |
3 | import android.util.Log;
4 |
5 | import tk.wlemuel.cotable.core.AppConfig;
6 |
7 |
8 | public class TLog {
9 | public static final String LOG_TAG = AppConfig.APP_NAME;
10 | public static boolean DEBUG = true;
11 |
12 | public TLog() {
13 | }
14 |
15 | public static void analytics(String log) {
16 | if (DEBUG)
17 | Log.d(LOG_TAG, log);
18 | }
19 |
20 | public static void error(String log) {
21 | if (DEBUG)
22 | Log.e(LOG_TAG, "" + log);
23 | }
24 |
25 | public static void log(String log) {
26 | if (DEBUG)
27 | Log.i(LOG_TAG, log);
28 | }
29 |
30 | public static void log(String tag, String log) {
31 | if (DEBUG)
32 | Log.i(tag, log);
33 | }
34 |
35 | public static void logv(String log) {
36 | if (DEBUG)
37 | Log.v(LOG_TAG, log);
38 | }
39 |
40 | public static void warning(String log) {
41 | if (DEBUG)
42 | Log.w(LOG_TAG, log);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/utils/TimeZoneUtil.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.utils;
2 |
3 | import java.util.Date;
4 | import java.util.TimeZone;
5 |
6 | /**
7 | * Utils for handling the timezone issues.
8 | *
9 | * @author HuangWenwei
10 | * @updated Steve Lemuel
11 | * @created 2014-07-31
12 | */
13 | public class TimeZoneUtil {
14 |
15 | /**
16 | * Returns if the timezone of current device is EasternEightZone (China).
17 | *
18 | * @return {@code true} if the timezone of current device is EasternEightZone,
19 | * {@code false} otherwise.
20 | */
21 | public static boolean isInEasternEightZones() {
22 | return TimeZone.getDefault() == TimeZone.getTimeZone("GMT+08");
23 | }
24 |
25 | /**
26 | * Convert the {@code date} according to the timezone.
27 | *
28 | * @param date the current date
29 | * @param oldZone old timezone
30 | * @param newZone new timezone
31 | * @return {@code finalDate} the converted date.
32 | */
33 | public static Date transformTime(Date date, TimeZone oldZone,
34 | TimeZone newZone) {
35 | Date finalDate = null;
36 | if (date != null) {
37 | int timeOffset = oldZone.getOffset(date.getTime())
38 | - newZone.getOffset(date.getTime());
39 | finalDate = new Date(date.getTime() - timeOffset);
40 | }
41 | return finalDate;
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/utils/UIHelper.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.utils;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.app.Activity;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.Bundle;
8 | import android.webkit.WebView;
9 |
10 | import java.util.Map;
11 |
12 | import tk.wlemuel.cotable.activity.common.SimpleBackActivity;
13 | import tk.wlemuel.cotable.model.SimpleBackPage;
14 |
15 | /**
16 | * UIHelper
17 | *
18 | * @author Steve Lemuel
19 | * @version 0.1
20 | * @desc UIHelper
21 | * @created 2015/05/11
22 | * @updated 2015/05/11
23 | */
24 | public class UIHelper {
25 |
26 | /**
27 | * Show Blog Details
28 | *
29 | * @param context context
30 | * @param blogInfo blog id
31 | */
32 | public static void showBlogDetail(Context context, Map blogInfo) {
33 | Bundle args = new Bundle();
34 |
35 | if (blogInfo != null) {
36 | for (Map.Entry entry : blogInfo.entrySet()) {
37 | args.putString(entry.getKey(), entry.getValue());
38 | }
39 | }
40 |
41 | showSimpleBack(context, SimpleBackPage.DETAILS, args);
42 | }
43 |
44 | /**
45 | * Call the system application with shares.
46 | *
47 | * @param context context
48 | * @param title share title
49 | * @param url share url
50 | */
51 | public static void showShareMore(Activity context, final String title, final String url) {
52 | Intent intent = new Intent(Intent.ACTION_SEND);
53 | intent.setType("text/plain");
54 | intent.putExtra(Intent.EXTRA_SUBJECT, "Share: " + title);
55 | intent.putExtra(Intent.EXTRA_TEXT, title + " " + url);
56 | context.startActivity(Intent.createChooser(intent, "Choose to share"));
57 | }
58 |
59 | public static void showSimpleBack(Context context, SimpleBackPage page) {
60 | Intent intent = new Intent(context, SimpleBackActivity.class);
61 | intent.putExtra(SimpleBackActivity.BUNDLE_KEY_PAGE, page.getValue());
62 |
63 | context.startActivity(intent);
64 | }
65 |
66 | public static void showSimpleBack(Context context, SimpleBackPage page,
67 | Bundle args) {
68 | Intent intent = new Intent(context, SimpleBackActivity.class);
69 | intent.putExtra(SimpleBackActivity.BUNDLE_KEY_ARGS, args);
70 | intent.putExtra(SimpleBackActivity.BUNDLE_KEY_PAGE, page.getValue());
71 | context.startActivity(intent);
72 | }
73 |
74 | /**
75 | * 添加网页的点击图片展示支持
76 | */
77 | @SuppressLint("JavascriptInterface")
78 | public static void addWebImageShow(final Context cxt, WebView wv) {
79 | wv.getSettings().setJavaScriptEnabled(true);
80 | wv.addJavascriptInterface(new OnWebViewImageListener() {
81 |
82 | @Override
83 | public void onImageClick(String bigImageUrl) {
84 | if (bigImageUrl != null) {
85 | // UIHelper.showImageZoomDialog(cxt, bigImageUrl);
86 | // UIHelper.showImagePreview(cxt, new String[]{bigImageUrl});
87 | }
88 | }
89 | }, "mWebViewImageListener");
90 | }
91 |
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/app/src/main/java/tk/wlemuel/cotable/utils/ViewUtils.java:
--------------------------------------------------------------------------------
1 | package tk.wlemuel.cotable.utils;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Activity;
5 | import android.app.Dialog;
6 | import android.content.Context;
7 | import android.graphics.Bitmap;
8 | import android.graphics.Canvas;
9 | import android.os.Build;
10 | import android.text.TextUtils;
11 | import android.util.TypedValue;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.widget.TextView;
15 |
16 | /**
17 | * ViewUtils
18 | *
19 | * @author Steve Lemuel
20 | * @version 0.1
21 | * @desc ViewUtils
22 | * @created 2015/05/10
23 | * @updated 2015/05/10
24 | */
25 | public final class ViewUtils {
26 |
27 | public static float a(TextView tv) {
28 | float f = 0.0F;
29 | if (tv != null) {
30 | float f1 = 0.0f;
31 | CharSequence text = tv.getText();
32 | if (!TextUtils.isEmpty(text)) {
33 | f1 = tv.getPaint().measureText(text.toString());
34 | }
35 | int i = tv.getPaddingLeft();
36 | int j = tv.getPaddingRight();
37 | f = f1 + (float) (j + i);
38 | }
39 | return f;
40 | }
41 |
42 | public static int a(Context context) {
43 | return (int) TypedValue.applyDimension(1, 40F, context.getResources()
44 | .getDisplayMetrics());
45 | }
46 |
47 | public static void a(Activity activity, int[] ai) {
48 | if (ai != null && activity != null) {
49 | int size = ai.length;
50 | for (int i = 0; i < size; i++) {
51 | View view = activity.findViewById(ai[i]);
52 | if (view != null)
53 | view.setOnClickListener((View.OnClickListener) activity);
54 | }
55 | }
56 | }
57 |
58 | public static void a(Dialog dialog, int[] ai) {
59 | if (ai != null && dialog != null) {
60 | int size = ai.length;
61 | for (int j = 0; j < size; j++) {
62 | View view = dialog.findViewById(ai[j]);
63 | if (view != null)
64 | view.setOnClickListener((View.OnClickListener) dialog);
65 | }
66 | }
67 | }
68 |
69 | public static void a(View view) {
70 | if (view != null && (view.getParent() instanceof ViewGroup))
71 | ((ViewGroup) view.getParent()).removeView(view);
72 | }
73 |
74 | public static void a(View view, int i) {
75 | if (view != null)
76 | view.setVisibility(i);
77 | }
78 |
79 | public static void a(View view, View.OnClickListener listener, int[] ai) {
80 | if (ai != null && view != null) {
81 | int size = ai.length;
82 | for (int j = 0; j < size; j++) {
83 | View view1 = view.findViewById(ai[j]);
84 | if (view1 != null)
85 | view1.setOnClickListener(listener);
86 | }
87 | }
88 | }
89 |
90 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
91 | public static Bitmap b(View view) {
92 | Bitmap bitmap = null;
93 | view.measure(View.MeasureSpec.makeMeasureSpec(0, 0),
94 | View.MeasureSpec.makeMeasureSpec(0, 0));
95 | int i = view.getMeasuredWidth();
96 | int j = view.getMeasuredHeight();
97 | view.layout(0, 0, i, j);
98 | view.setDrawingCacheEnabled(false);
99 | view.setWillNotCacheDrawing(true);
100 | view.setDrawingCacheEnabled(false);
101 | view.setWillNotCacheDrawing(true);
102 | if (i > 0 && j > 0) {
103 | bitmap = Bitmap.createBitmap(i, j,
104 | Bitmap.Config.ARGB_8888);
105 | Canvas canvas = new Canvas(bitmap);
106 | if (Build.VERSION.SDK_INT >= 11)
107 | view.setLayerType(1, null);
108 | view.draw(canvas);
109 | }
110 | return bitmap;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/app/src/main/res/anim/progressbar_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_add_white_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/ic_add_white_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/ic_comment.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_comment_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/ic_comment_active.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_dianzan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/ic_dianzan.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_dianzan_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/ic_dianzan_active.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_pullrefresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/ic_pullrefresh.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_reply.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/ic_reply.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_reply_active.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/ic_reply_active.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_scrolltoup_24dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/ic_scrolltoup_24dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/main_bottombtn_down.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/main_bottombtn_down.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/main_bottombtn_up.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/main_bottombtn_up.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/main_icon_zoomin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/main_icon_zoomin.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/main_icon_zoomin_dis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/main_icon_zoomin_dis.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/main_icon_zoomout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/main_icon_zoomout.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/main_icon_zoomout_dis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/main_icon_zoomout_dis.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/main_topbtn_down.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/main_topbtn_down.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/main_topbtn_up.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/main_topbtn_up.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/main_zoomin.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/main_zoomout.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/spinner_48_inner_holo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/spinner_48_inner_holo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/spinner_48_outer_holo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-hdpi/spinner_48_outer_holo.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_avatar_author.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-mdpi/ic_avatar_author.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/actionbar_back_icon_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/actionbar_back_icon_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/animdraw.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bg_splash_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/bg_splash_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/btn_menu_about_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/btn_menu_about_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/btn_menu_about_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/btn_menu_about_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/btn_menu_close_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/btn_menu_close_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/btn_menu_close_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/btn_menu_close_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/btn_menu_day_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/btn_menu_day_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/btn_menu_daymode_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/btn_menu_daymode_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/btn_menu_night_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/btn_menu_night_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/btn_menu_night_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/btn_menu_night_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/btn_menu_options_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/btn_menu_options_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/btn_menu_options_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/btn_menu_options_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/drawer_left_header.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/drawer_left_header.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_avatar_author.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/ic_avatar_author.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_blog_item_avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/ic_blog_item_avatar.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_default_avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/ic_default_avatar.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/loadingpage_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/loadingpage_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/loadingpage_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/loadingpage_light.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/page_icon_network.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/page_icon_network.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/pagefailed_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/pagefailed_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/tab_notification_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xhdpi/tab_notification_bg.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_avatar_author.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xxhdpi/ic_avatar_author.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_drawer_left_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/list_cell_background_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/main_bottombutton.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/main_topbutton.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/progress_medium_holo.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | -
19 |
25 |
26 | -
27 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/tab_strip_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
15 |
16 |
20 |
21 |
25 |
26 |
27 |
28 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_blog_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_blog_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
18 |
19 |
25 |
26 |
37 |
38 |
44 |
45 |
46 |
51 |
52 |
59 |
60 |
61 |
66 |
67 |
77 |
78 |
86 |
87 |
96 |
97 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_drawer_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
16 |
17 |
24 |
25 |
34 |
35 |
45 |
46 |
47 |
48 |
55 |
56 |
57 |
58 |
62 |
63 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_drawer_left_divider.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_drawer_left_list_group.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
20 |
21 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_drawer_left_list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main_drawer_left_setting_bar.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
21 |
22 |
32 |
33 |
34 |
40 |
41 |
47 |
48 |
58 |
59 |
60 |
66 |
67 |
73 |
74 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/aty_detail.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/aty_simple_fragment.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/aty_splash_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_blog_detail.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
21 |
22 |
26 |
27 |
28 |
33 |
34 |
35 |
36 |
44 |
45 |
46 |
53 |
54 |
61 |
62 |
63 |
64 |
65 |
71 |
72 |
76 |
77 |
84 |
88 |
95 |
96 |
102 |
108 |
109 |
116 |
117 |
123 |
129 |
136 |
137 |
138 |
139 |
140 |
141 |
146 |
147 |
148 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_swipe_refresh_recycleview.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
20 |
21 |
22 |
23 |
24 |
36 |
37 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_viewpager.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_cell_blog.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
24 |
25 |
36 |
37 |
43 |
44 |
45 |
50 |
51 |
58 |
59 |
66 |
67 |
68 |
73 |
74 |
84 |
85 |
93 |
94 |
103 |
104 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_cell_footer.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
21 |
22 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tab_layout_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
22 |
23 |
24 |
32 |
33 |
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_error_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
13 |
18 |
19 |
23 |
24 |
31 |
32 |
33 |
40 |
41 |
42 |
43 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_toast.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
26 |
27 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/view_toolbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-en-rUS/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Cotable
3 | Steve Lemuel
4 | wlemuel
5 | wlemuel@hotmail.com
6 | 1078707962
7 | 1078707962@qq.com
8 | http://wlemuel.tk
9 |
10 | User
11 | Favors
12 | Setting
13 | Exit
14 | Close
15 | Open
16 | Search
17 | Comments (%d)
18 | Posted at :
19 | Read (%d)
20 | Click to refresh
21 | Loading...
22 | No data
23 | JAVA EXCEPTION HANDLE
24 | days ago
25 | hours ago
26 | a minute ago
27 | an hour ago
28 | minutes ago
29 | the day before yesterday
30 | yesterday
31 | @string/app_author
32 | About
33 | Content
34 | Preferences
35 | Loading...
36 | Loading Error.
37 | No more data
38 | Network Unavailable
39 | LATEST
40 | RECOMMEND
41 | NEWS
42 | Author :
43 | Network Error
44 | 2015-04-19 14:52
45 | 想到用python发送邮件主要是服务器 有时候会产生coredump文件 ,然后因为脚本重启原因,服务器coredump产生后会重启但是没有主动通知开发人员想了下可以写个脚本一旦产生coredump文件就可以发送邮件给开发者让其立马知道下面只介绍简单的发送脚本如果需要在生产环境用起来 还需要按要求修...
46 | Developer
47 | Instructions
48 | License
49 | Source
50 | Update
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/values-ja-rJP/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | コタブル
3 | オウシン
4 | wlemuel
5 | wlemuel@hotmail.com
6 | 1078707962
7 | 1078707962@qq.com
8 | http://wlemuel.tk
9 |
10 | ユーザ
11 | クリップ
12 | 設定
13 | 終了
14 | 閉じる
15 | 開く
16 | 検索
17 | コメント (%d)
18 | 再ロード
19 | ロード中
20 | JAVAの異常処理
21 | 日前
22 | 1分間前
23 | 1時間前
24 | 発表時間 :
25 | 読み (%d)
26 | 昨日
27 | おととい
28 | @string/app_author
29 | 設定
30 | ブログ内容
31 |
32 | ネトワクに接続できません。
33 | データなし
34 | 2015-04-19 14:52
35 | 想到用python发送邮件主要是服务器 有时候会产生coredump文件 ,然后因为脚本重启原因,服务器coredump产生后会重启但是没有主动通知开发人员想了下可以写个脚本一旦产生coredump文件就可以发送邮件给开发者让其立马知道下面只介绍简单的发送脚本如果需要在生产环境用起来 还需要按要求修...
36 | 作者 :
37 | 時間前
38 | ロード中...
39 | エラー発生
40 | ネトワクエラー
41 | 分前
42 | 最新ボログ
43 | オススメ
44 | 最新情報
45 | データなし
46 |
47 |
48 | - Java
49 | - C++
50 | - Python
51 | - Ruby
52 | - PHP
53 | - Objective-C
54 | - Perl
55 |
56 | エンジニア
57 | 機能紹介
58 | 更新ローグ
59 | ライセンス
60 | ソースコード
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | #2196F3
6 | #1976D2
7 | #BBDEFB
8 | #ff303030
9 | #ff000000
10 | #ff252525
11 |
12 | #8BC34A
13 | #1976D2
14 |
15 | #212121
16 | #727272
17 | #B6B6B6
18 |
19 | #DE000000
20 | #9E9E9E
21 |
22 |
23 | @color/colorPrimary
24 | #40AA53
25 | #9A9A9A
26 | #353535
27 | #576B95
28 | #ff000000
29 | #ffffffff
30 | #9A9A9A
31 | @color/text_color_black
32 | #00000000
33 | #ffffffff
34 |
35 |
36 | #fff
37 | #000
38 | #9A9A9A
39 | #e9eff3
40 |
41 |
42 | @color/text_color_white
43 | @color/main
44 |
45 |
46 | @color/toolbar_text_color
47 | @color/toolbar_background
48 | @color/main
49 | @color/main_black
50 | #66fafafa
51 |
52 |
53 | @color/main
54 | @color/text_color_white
55 |
56 |
57 | #757575
58 | @color/text_color_black
59 | #ffffffff
60 | #F1F1F1
61 |
62 |
63 | @color/list_item_background_normal
64 | #EEEEEE
65 | @color/list_item_background_pressed
66 | @color/main
67 | #757575
68 | #FF3B6E75
69 | @color/text_color_black
70 |
71 |
72 | @color/window_background
73 | @color/text_color_white
74 | @color/drawer_left_header_username
75 | @color/list_divider_color
76 | @color/list_divider_color
77 | @color/list_item_background_normal
78 | @color/drawer_left_list_item_ic_color
79 |
80 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
7 | 20dip
8 | 16sp
9 | 4dip
10 | 6dip
11 | 16dip
12 | 40.0dip
13 |
14 | 8.0dip
15 | 55.0dip
16 | 16.0dip
17 | 10.0dip
18 |
19 |
20 | 280dp
21 | 160dp
22 | 70dp
23 | 35dp
24 | 2dp
25 | 20dp
26 | 15sp
27 |
28 | 48dp
29 | 24sp
30 | 24dp
31 | 16sp
32 | 42dp
33 | 8dp
34 | 48dp
35 | 14sp
36 | 20sp
37 |
38 | 60dp
39 | 8dp
40 | 6dp
41 | 25dp
42 | 10sp
43 |
44 |
45 | 16dp
46 | 18sp
47 | 8dp
48 | 8dp
49 | 10sp
50 | 10sp
51 | 5dp
52 | 10sp
53 | 10sp
54 | 5dp
55 | 10sp
56 | 12dp
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 码厩
4 | 激荡的天石
5 | wlemuel
6 | wlemuel@hotmail.com
7 | 1078707962
8 | 1078707962@qq.com
9 | http://wlemuel.tk
10 |
11 | 打开
12 | 关闭
13 |
14 |
15 | - Java
16 | - C++
17 | - Python
18 | - Ruby
19 | - PHP
20 | - Objective-C
21 | - Perl
22 |
23 |
24 | JAVA异常处理、常用类、反射、集合
25 | 想到用python发送邮件主要是服务器 有时候会产生coredump文件 ,然后因为脚本重启原因,服务器coredump产生后会重启但是没有主动通知开发人员想了下可以写个脚本一旦产生coredump文件就可以发送邮件给开发者让其立马知道下面只介绍简单的发送脚本如果需要在生产环境用起来 还需要按要求修...
26 | @string/app_author
27 | 2015-04-19 14:52
28 | 评论 (%d)
29 | 阅读 (%d)
30 | 发布时间:
31 | 作者 :
32 |
33 |
34 | 点击屏幕, 重新加载
35 | 暂无内容
36 | 加载中...
37 | 没有网络连接
38 |
39 |
40 | 分钟前
41 | 小时前
42 | 天前
43 | 1分钟前
44 | 1小时前
45 | 昨天
46 | 前天
47 |
48 | 加载中...
49 | 没有更多数据
50 | 网络不稳定,加载出错
51 | 没有可用的网络
52 |
53 | 最新博客
54 | 推荐阅读
55 | 资讯新闻
56 |
57 | 设置
58 | 关于
59 | 博客内容
60 | 退出
61 | 收藏
62 | 搜索
63 | 设置
64 | 用户
65 |
66 | 开发者
67 | 源代码
68 | 功能介绍
69 | 开源协议
70 | 更新日志
71 |
72 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
15 |
26 |
27 |
30 |
31 |
34 |
35 |
36 |
37 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.2.2'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/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
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 10 15:27:10 PDT 2013
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-2.2.1-all.zip
7 |
--------------------------------------------------------------------------------
/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 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/screenshot/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wlemuel/Cotable/ddeee9adfa1ceb5459ccb9109235879a70eaa6b7/screenshot/screenshot.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app' //, 'library-pulltorefresh' , ':library-photoview', ':library-viewpager-indicator',
2 | //':library-sticky-listheaders', ':library-umengshare'
3 | //project(':library-photoview').projectDir = new File('libraries/library-photoview')
4 | //project(':library-viewpager-indicator').projectDir = new File('libraries/library-viewpager-indicator')
5 | //project(':library-sticky-listheaders').projectDir = new File('libraries/library-sticky-listheaders')
6 | //project(':library-umengshare').projectDir = new File('libraries/library-umengshare')
7 | //project(':library-pulltorefresh').projectDir = new File('libraries/library-pulltorefresh')
--------------------------------------------------------------------------------