├── .gitignore ├── LICENSE ├── ONE-Unofficial.iml ├── PullToRefresh ├── Android-PullToRefresh.iml ├── LICENSE ├── PullToRefresh.iml ├── README.md ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── handmark │ │ └── pulltorefresh │ │ ├── extras │ │ ├── listfragment │ │ │ ├── PullToRefreshBaseListFragment.java │ │ │ ├── PullToRefreshExpandableListFragment.java │ │ │ └── PullToRefreshListFragment.java │ │ └── viewpager │ │ │ └── PullToRefreshViewPager.java │ │ └── library │ │ ├── ILoadingLayout.java │ │ ├── IPullToRefresh.java │ │ ├── LoadingLayoutProxy.java │ │ ├── OverscrollHelper.java │ │ ├── PullToRefreshAdapterViewBase.java │ │ ├── PullToRefreshBase.java │ │ ├── PullToRefreshExpandableListView.java │ │ ├── PullToRefreshGridView.java │ │ ├── PullToRefreshHorizontalScrollView.java │ │ ├── PullToRefreshListView.java │ │ ├── PullToRefreshScrollView.java │ │ ├── PullToRefreshWebView.java │ │ ├── extras │ │ ├── PullToRefreshWebView2.java │ │ └── SoundPullEventListener.java │ │ └── internal │ │ ├── EmptyViewMethodAccessor.java │ │ ├── FlipLoadingLayout.java │ │ ├── IndicatorLayout.java │ │ ├── LoadingLayout.java │ │ ├── RotateLoadingLayout.java │ │ ├── Utils.java │ │ └── ViewCompat.java │ └── res │ ├── anim │ ├── slide_in_from_bottom.xml │ ├── slide_in_from_top.xml │ ├── slide_out_to_bottom.xml │ └── slide_out_to_top.xml │ ├── drawable-hdpi │ ├── default_ptr_flip.png │ ├── default_ptr_rotate.png │ └── indicator_arrow.png │ ├── drawable-xhdpi │ ├── default_ptr_flip.png │ ├── default_ptr_rotate.png │ └── indicator_arrow.png │ ├── drawable │ ├── indicator_bg_bottom.xml │ └── indicator_bg_top.xml │ ├── layout │ ├── pull_to_refresh_header_horizontal.xml │ └── pull_to_refresh_header_vertical.xml │ ├── values-ar │ └── pull_refresh_strings.xml │ ├── values-cs │ └── pull_refresh_strings.xml │ ├── values-de │ └── pull_refresh_strings.xml │ ├── values-es │ └── pull_refresh_strings.xml │ ├── values-fi │ └── pull_refresh_strings.xml │ ├── values-fr │ └── pull_refresh_strings.xml │ ├── values-he │ └── pull_refresh_strings.xml │ ├── values-it │ └── pull_refresh_strings.xml │ ├── values-iw │ └── pull_refresh_strings.xml │ ├── values-ja │ └── pull_refresh_strings.xml │ ├── values-ko │ └── pull_refresh_strings.xml │ ├── values-nl │ └── pull_refresh_strings.xml │ ├── values-pl │ └── pull_refresh_strings.xml │ ├── values-pt-rBR │ └── pull_refresh_strings.xml │ ├── values-pt │ └── pull_refresh_strings.xml │ ├── values-ro │ └── pull_refresh_strings.xml │ ├── values-ru │ └── pull_refresh_strings.xml │ ├── values-zh │ └── pull_refresh_strings.xml │ └── values │ ├── attrs.xml │ ├── dimens.xml │ ├── ids.xml │ └── pull_refresh_strings.xml ├── README.md ├── Screenshots ├── screenshot-1.png ├── screenshot-2.png ├── screenshot-3.png ├── screenshot-4.png ├── screenshot-5.png ├── screenshot-6.png └── screenshot-7.jpg ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── com.umeng.fb.5.4.0.jar │ ├── fastjson-1.2.6.jar │ └── umeng-update-v2.6.0.1.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── studio │ │ └── uphie │ │ └── one │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── welcome.gif │ ├── java │ └── studio │ │ └── uphie │ │ └── one │ │ ├── abs │ │ ├── AbsBaseActivity.java │ │ ├── AbsBaseFragment.java │ │ └── AbsModuleFragment.java │ │ ├── common │ │ ├── Api.java │ │ ├── App.java │ │ ├── Constants.java │ │ ├── HttpClient.java │ │ ├── HttpData.java │ │ └── HttpError.java │ │ ├── interfaces │ │ ├── IHttp.java │ │ ├── IInit.java │ │ ├── IShare.java │ │ ├── OnNetConnChangeListener.java │ │ └── ShareChannel.java │ │ ├── ui │ │ ├── FragmentAdapter.java │ │ ├── MainActivity.java │ │ ├── WelcomeActivity.java │ │ ├── article │ │ │ ├── Article.java │ │ │ ├── ArticleContentFragment.java │ │ │ └── ArticleFragment.java │ │ ├── home │ │ │ ├── Home.java │ │ │ ├── HomeContentFragment.java │ │ │ └── HomeFragment.java │ │ ├── personal │ │ │ ├── AboutActivity.java │ │ │ ├── FeedbackActivity.java │ │ │ └── PersonalFragment.java │ │ ├── question │ │ │ ├── Question.java │ │ │ ├── QuestionContentFragment.java │ │ │ └── QuestionFragment.java │ │ └── thing │ │ │ ├── Thing.java │ │ │ ├── ThingContentFragment.java │ │ │ └── ThingFragment.java │ │ ├── utils │ │ ├── ConfigUtil.java │ │ ├── CrashHandler.java │ │ ├── FileManager.java │ │ ├── ImageUtil.java │ │ ├── JsonUtil.java │ │ ├── NetworkUtil.java │ │ ├── SysUtil.java │ │ ├── TextToast.java │ │ └── TimeUtil.java │ │ └── widgets │ │ ├── ClearEditText.java │ │ ├── LikeView.java │ │ └── Tab.java │ └── res │ ├── drawable-hdpi │ ├── bg_home_saying.9.png │ ├── bg_msg_left_highlighted.9.png │ ├── bg_msg_left_normal.9.png │ ├── bg_msg_right_highlighted.9.png │ ├── bg_msg_right_normal.9.png │ ├── ic_answer.png │ ├── ic_avatar_default.jpg │ ├── ic_back.png │ ├── ic_like.png │ ├── ic_liked.png │ ├── ic_more.png │ ├── ic_question.png │ ├── ic_title.png │ └── ic_to.png │ ├── drawable-xhdpi │ ├── ic_msg_fail.png │ ├── logo_facebook.png │ ├── logo_google_plus.png │ ├── logo_qq.png │ ├── logo_qzone.png │ ├── logo_sinaweibo.png │ ├── logo_twitter.png │ └── logo_wechat.png │ ├── drawable-xxhdpi │ ├── av_author.jpg │ └── ic_clear.png │ ├── drawable │ ├── actionbar.xml │ ├── bg_bottom_line_blue.xml │ ├── bg_bottom_line_gray.xml │ ├── bg_bottom_line_gray_slim.xml │ ├── bg_frame_white.xml │ ├── bg_top_line.xml │ ├── checkbox_like.xml │ ├── divider_light_gray.xml │ ├── picture_holder.xml │ ├── selector_edittext.xml │ ├── selector_msg_left.xml │ ├── selector_msg_right.xml │ ├── selector_ok_text.xml │ ├── selector_text_send.xml │ ├── share_background.xml │ ├── tab.xml │ ├── umeng_common_gradient_orange.xml │ └── umeng_common_gradient_red.xml │ ├── layout │ ├── actionbar.xml │ ├── actionbar_main.xml │ ├── actionbar_secondary.xml │ ├── activity_about.xml │ ├── activity_feedback.xml │ ├── activity_main.xml │ ├── activity_welcome.xml │ ├── dialog_update.xml │ ├── divider_gray_line.xml │ ├── fragment_article.xml │ ├── fragment_home.xml │ ├── fragment_personal.xml │ ├── fragment_question.xml │ ├── fragment_thing.xml │ ├── layout_article.xml │ ├── layout_home.xml │ ├── layout_question.xml │ ├── layout_thing.xml │ ├── list_item_conversion_left.xml │ ├── list_item_conversion_right.xml │ ├── loading_window.xml │ ├── menu_share.xml │ └── umeng_common_download_notification.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-en │ └── strings.xml │ ├── values-zh-rTW │ └── strings.xml │ └── values │ ├── attr.xml │ ├── color.xml │ ├── strings.xml │ ├── styles.xml │ ├── tb_munion_strings.xml │ ├── umeng_common_strings.xml │ └── umeng_update_string.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── keystore.jks ├── release └── release-2016-2-19.apk └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /PullToRefresh/build 8 | /captures 9 | .idea/.name 10 | .idea/copyright/profiles_settings.xml 11 | .idea/misc.xml 12 | .idea/gradle.xml 13 | app/app.iml 14 | .idea/vcs.xml 15 | .idea/encodings.xml 16 | .idea/modules.xml 17 | .idea/runConfigurations.xml 18 | .idea/compiler.xml 19 | -------------------------------------------------------------------------------- /ONE-Unofficial.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /PullToRefresh/README.md: -------------------------------------------------------------------------------- 1 | ##Android—PullToRefresh修改项目 2 | 3 | 这是修改目录结构以满足AndroidStudio导入后的项目, 4 | 相关参考项目我稍后会上传。 5 | 配置相关参见我的博客: 6 | http://www.cnblogs.com/lhyz/p/4401911.html 7 | 8 | \n 9 | 10 | 由于未解决的错误,在sample文件夹中的项目无法上传,现改为一个单独的仓库Samples来存储示例项目, 11 | 12 | \n 13 | 14 | 这个项目的示例在这个仓库目录下: 15 | https://github.com/wylhyz/Samples/tree/master/PullrefreshLib 16 | -------------------------------------------------------------------------------- /PullToRefresh/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:1.5.0' 9 | } 10 | } 11 | 12 | android { 13 | compileSdkVersion 22 14 | buildToolsVersion = '23.0.1' 15 | } 16 | 17 | dependencies { 18 | compile 'com.android.support:support-v4:22.0.0' 19 | } -------------------------------------------------------------------------------- /PullToRefresh/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/extras/listfragment/PullToRefreshBaseListFragment.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.extras.listfragment; 17 | 18 | import android.os.Bundle; 19 | import android.support.v4.app.ListFragment; 20 | import android.view.LayoutInflater; 21 | import android.view.View; 22 | import android.view.ViewGroup; 23 | import android.widget.AbsListView; 24 | import android.widget.ListView; 25 | 26 | import com.handmark.pulltorefresh.library.PullToRefreshBase; 27 | 28 | abstract class PullToRefreshBaseListFragment> extends ListFragment { 29 | 30 | private T mPullToRefreshListView; 31 | 32 | @Override 33 | public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 34 | View layout = super.onCreateView(inflater, container, savedInstanceState); 35 | 36 | ListView lv = (ListView) layout.findViewById(android.R.id.list); 37 | ViewGroup parent = (ViewGroup) lv.getParent(); 38 | 39 | // Remove ListView and add PullToRefreshListView in its place 40 | int lvIndex = parent.indexOfChild(lv); 41 | parent.removeViewAt(lvIndex); 42 | mPullToRefreshListView = onCreatePullToRefreshListView(inflater, savedInstanceState); 43 | parent.addView(mPullToRefreshListView, lvIndex, lv.getLayoutParams()); 44 | 45 | return layout; 46 | } 47 | 48 | /** 49 | * @return The {@link PullToRefreshBase} attached to this ListFragment. 50 | */ 51 | public final T getPullToRefreshListView() { 52 | return mPullToRefreshListView; 53 | } 54 | 55 | /** 56 | * Returns the {@link PullToRefreshBase} which will replace the ListView 57 | * created from ListFragment. You should override this method if you wish to 58 | * customise the {@link PullToRefreshBase} from the default. 59 | * 60 | * @param inflater - LayoutInflater which can be used to inflate from XML. 61 | * @param savedInstanceState - Bundle passed through from 62 | * {@link ListFragment#onCreateView(LayoutInflater, ViewGroup, Bundle) 63 | * onCreateView(...)} 64 | * @return The {@link PullToRefreshBase} which will replace the ListView. 65 | */ 66 | protected abstract T onCreatePullToRefreshListView(LayoutInflater inflater, Bundle savedInstanceState); 67 | 68 | } -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/extras/listfragment/PullToRefreshExpandableListFragment.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.extras.listfragment; 17 | 18 | import android.os.Bundle; 19 | import android.support.v4.app.ListFragment; 20 | import android.view.LayoutInflater; 21 | 22 | import com.handmark.pulltorefresh.library.PullToRefreshExpandableListView; 23 | 24 | /** 25 | * A sample implementation of how to use {@link PullToRefreshExpandableListView} 26 | * with {@link ListFragment}. This implementation simply replaces the ListView 27 | * that {@code ListFragment} creates with a new 28 | * {@code PullToRefreshExpandableListView}. This means that ListFragment still 29 | * works 100% (e.g. setListShown(...) ). 30 | *

31 | * The new PullToRefreshListView is created in the method 32 | * {@link #onCreatePullToRefreshListView(LayoutInflater, Bundle)}. If you wish 33 | * to customise the {@code PullToRefreshExpandableListView} then override this 34 | * method and return your customised instance. 35 | * 36 | * @author Chris Banes 37 | * 38 | */ 39 | public class PullToRefreshExpandableListFragment extends PullToRefreshBaseListFragment { 40 | 41 | protected PullToRefreshExpandableListView onCreatePullToRefreshListView(LayoutInflater inflater, 42 | Bundle savedInstanceState) { 43 | return new PullToRefreshExpandableListView(getActivity()); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/extras/listfragment/PullToRefreshListFragment.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.extras.listfragment; 17 | 18 | import android.os.Bundle; 19 | import android.support.v4.app.ListFragment; 20 | import android.view.LayoutInflater; 21 | 22 | import com.handmark.pulltorefresh.library.PullToRefreshListView; 23 | 24 | /** 25 | * A sample implementation of how to use {@link PullToRefreshListView} with 26 | * {@link ListFragment}. This implementation simply replaces the ListView that 27 | * {@code ListFragment} creates with a new PullToRefreshListView. This means 28 | * that ListFragment still works 100% (e.g. setListShown(...) ). 29 | *

30 | * The new PullToRefreshListView is created in the method 31 | * {@link #onCreatePullToRefreshListView(LayoutInflater, Bundle)}. If you wish 32 | * to customise the {@code PullToRefreshListView} then override this method and 33 | * return your customised instance. 34 | * 35 | * @author Chris Banes 36 | * 37 | */ 38 | public class PullToRefreshListFragment extends PullToRefreshBaseListFragment { 39 | 40 | protected PullToRefreshListView onCreatePullToRefreshListView(LayoutInflater inflater, Bundle savedInstanceState) { 41 | return new PullToRefreshListView(getActivity()); 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/extras/viewpager/PullToRefreshViewPager.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.extras.viewpager; 17 | 18 | import android.content.Context; 19 | import android.support.v4.view.PagerAdapter; 20 | import android.support.v4.view.ViewPager; 21 | import android.support.v4.view.ViewPager.OnPageChangeListener; 22 | import android.util.AttributeSet; 23 | 24 | import com.handmark.pulltorefresh.library.PullToRefreshBase; 25 | import com.handmark.pulltorefresh.R; 26 | 27 | public class PullToRefreshViewPager extends PullToRefreshBase { 28 | 29 | public PullToRefreshViewPager(Context context) { 30 | super(context); 31 | } 32 | 33 | public PullToRefreshViewPager(Context context, AttributeSet attrs) { 34 | super(context, attrs); 35 | } 36 | 37 | @Override 38 | public final Orientation getPullToRefreshScrollDirection() { 39 | return Orientation.HORIZONTAL; 40 | } 41 | 42 | @Override 43 | protected ViewPager createRefreshableView(Context context, AttributeSet attrs) { 44 | ViewPager viewPager = new ViewPager(context, attrs); 45 | viewPager.setId(R.id.viewpager); 46 | return viewPager; 47 | } 48 | 49 | @Override 50 | protected boolean isReadyForPullStart() { 51 | ViewPager refreshableView = getRefreshableView(); 52 | 53 | PagerAdapter adapter = refreshableView.getAdapter(); 54 | if (null != adapter) { 55 | return refreshableView.getCurrentItem() == 0; 56 | } 57 | 58 | return false; 59 | } 60 | 61 | @Override 62 | protected boolean isReadyForPullEnd() { 63 | ViewPager refreshableView = getRefreshableView(); 64 | 65 | PagerAdapter adapter = refreshableView.getAdapter(); 66 | if (null != adapter) { 67 | return refreshableView.getCurrentItem() == adapter.getCount() - 1; 68 | } 69 | 70 | return false; 71 | } 72 | 73 | public void setAdapter(PagerAdapter pagerAdapter) { 74 | getRefreshableView().setAdapter(pagerAdapter); 75 | } 76 | 77 | public void setOnPageChangeListener(OnPageChangeListener onPageChangeListener) { 78 | getRefreshableView().setOnPageChangeListener(onPageChangeListener); 79 | } 80 | 81 | public int getCurrentItem() { 82 | return getRefreshableView().getCurrentItem(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/library/ILoadingLayout.java: -------------------------------------------------------------------------------- 1 | package com.handmark.pulltorefresh.library; 2 | 3 | import android.graphics.Typeface; 4 | import android.graphics.drawable.Drawable; 5 | 6 | public interface ILoadingLayout { 7 | 8 | /** 9 | * Set the Last Updated Text. This displayed under the main label when 10 | * Pulling 11 | * 12 | * @param label - Label to set 13 | */ 14 | public void setLastUpdatedLabel(CharSequence label); 15 | 16 | /** 17 | * Set the drawable used in the loading layout. This is the same as calling 18 | * setLoadingDrawable(drawable, Mode.BOTH) 19 | * 20 | * @param drawable - Drawable to display 21 | */ 22 | public void setLoadingDrawable(Drawable drawable); 23 | 24 | /** 25 | * Set Text to show when the Widget is being Pulled 26 | * setPullLabel(releaseLabel, Mode.BOTH) 27 | * 28 | * @param pullLabel - CharSequence to display 29 | */ 30 | public void setPullLabel(CharSequence pullLabel); 31 | 32 | /** 33 | * Set Text to show when the Widget is refreshing 34 | * setRefreshingLabel(releaseLabel, Mode.BOTH) 35 | * 36 | * @param refreshingLabel - CharSequence to display 37 | */ 38 | public void setRefreshingLabel(CharSequence refreshingLabel); 39 | 40 | /** 41 | * Set Text to show when the Widget is being pulled, and will refresh when 42 | * released. This is the same as calling 43 | * setReleaseLabel(releaseLabel, Mode.BOTH) 44 | * 45 | * @param releaseLabel - CharSequence to display 46 | */ 47 | public void setReleaseLabel(CharSequence releaseLabel); 48 | 49 | /** 50 | * Set's the Sets the typeface and style in which the text should be 51 | * displayed. Please see 52 | * {@link android.widget.TextView#setTypeface(Typeface) 53 | * TextView#setTypeface(Typeface)}. 54 | */ 55 | public void setTextTypeface(Typeface tf); 56 | 57 | } 58 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/library/LoadingLayoutProxy.java: -------------------------------------------------------------------------------- 1 | package com.handmark.pulltorefresh.library; 2 | 3 | import java.util.HashSet; 4 | 5 | import android.graphics.Typeface; 6 | import android.graphics.drawable.Drawable; 7 | 8 | import com.handmark.pulltorefresh.library.internal.LoadingLayout; 9 | 10 | public class LoadingLayoutProxy implements ILoadingLayout { 11 | 12 | private final HashSet mLoadingLayouts; 13 | 14 | LoadingLayoutProxy() { 15 | mLoadingLayouts = new HashSet(); 16 | } 17 | 18 | /** 19 | * This allows you to add extra LoadingLayout instances to this proxy. This 20 | * is only necessary if you keep your own instances, and want to have them 21 | * included in any 22 | * {@link PullToRefreshBase#createLoadingLayoutProxy(boolean, boolean) 23 | * createLoadingLayoutProxy(...)} calls. 24 | * 25 | * @param layout - LoadingLayout to have included. 26 | */ 27 | public void addLayout(LoadingLayout layout) { 28 | if (null != layout) { 29 | mLoadingLayouts.add(layout); 30 | } 31 | } 32 | 33 | @Override 34 | public void setLastUpdatedLabel(CharSequence label) { 35 | for (LoadingLayout layout : mLoadingLayouts) { 36 | layout.setLastUpdatedLabel(label); 37 | } 38 | } 39 | 40 | @Override 41 | public void setLoadingDrawable(Drawable drawable) { 42 | for (LoadingLayout layout : mLoadingLayouts) { 43 | layout.setLoadingDrawable(drawable); 44 | } 45 | } 46 | 47 | @Override 48 | public void setRefreshingLabel(CharSequence refreshingLabel) { 49 | for (LoadingLayout layout : mLoadingLayouts) { 50 | layout.setRefreshingLabel(refreshingLabel); 51 | } 52 | } 53 | 54 | @Override 55 | public void setPullLabel(CharSequence label) { 56 | for (LoadingLayout layout : mLoadingLayouts) { 57 | layout.setPullLabel(label); 58 | } 59 | } 60 | 61 | @Override 62 | public void setReleaseLabel(CharSequence label) { 63 | for (LoadingLayout layout : mLoadingLayouts) { 64 | layout.setReleaseLabel(label); 65 | } 66 | } 67 | 68 | public void setTextTypeface(Typeface tf) { 69 | for (LoadingLayout layout : mLoadingLayouts) { 70 | layout.setTextTypeface(tf); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshExpandableListView.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library; 17 | 18 | import android.annotation.TargetApi; 19 | import android.content.Context; 20 | import android.os.Build.VERSION; 21 | import android.os.Build.VERSION_CODES; 22 | import android.util.AttributeSet; 23 | import android.view.View; 24 | import android.widget.ExpandableListView; 25 | 26 | import com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor; 27 | 28 | public class PullToRefreshExpandableListView extends PullToRefreshAdapterViewBase { 29 | 30 | public PullToRefreshExpandableListView(Context context) { 31 | super(context); 32 | } 33 | 34 | public PullToRefreshExpandableListView(Context context, AttributeSet attrs) { 35 | super(context, attrs); 36 | } 37 | 38 | public PullToRefreshExpandableListView(Context context, Mode mode) { 39 | super(context, mode); 40 | } 41 | 42 | public PullToRefreshExpandableListView(Context context, Mode mode, AnimationStyle style) { 43 | super(context, mode, style); 44 | } 45 | 46 | @Override 47 | public final Orientation getPullToRefreshScrollDirection() { 48 | return Orientation.VERTICAL; 49 | } 50 | 51 | @Override 52 | protected ExpandableListView createRefreshableView(Context context, AttributeSet attrs) { 53 | final ExpandableListView lv; 54 | if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { 55 | lv = new InternalExpandableListViewSDK9(context, attrs); 56 | } else { 57 | lv = new InternalExpandableListView(context, attrs); 58 | } 59 | 60 | // Set it to this so it can be used in ListActivity/ListFragment 61 | lv.setId(android.R.id.list); 62 | return lv; 63 | } 64 | 65 | class InternalExpandableListView extends ExpandableListView implements EmptyViewMethodAccessor { 66 | 67 | public InternalExpandableListView(Context context, AttributeSet attrs) { 68 | super(context, attrs); 69 | } 70 | 71 | @Override 72 | public void setEmptyView(View emptyView) { 73 | PullToRefreshExpandableListView.this.setEmptyView(emptyView); 74 | } 75 | 76 | @Override 77 | public void setEmptyViewInternal(View emptyView) { 78 | super.setEmptyView(emptyView); 79 | } 80 | } 81 | 82 | @TargetApi(9) 83 | final class InternalExpandableListViewSDK9 extends InternalExpandableListView { 84 | 85 | public InternalExpandableListViewSDK9(Context context, AttributeSet attrs) { 86 | super(context, attrs); 87 | } 88 | 89 | @Override 90 | protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, 91 | int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { 92 | 93 | final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, 94 | scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); 95 | 96 | // Does all of the hard work... 97 | OverscrollHelper.overScrollBy(PullToRefreshExpandableListView.this, deltaX, scrollX, deltaY, scrollY, 98 | isTouchEvent); 99 | 100 | return returnValue; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshGridView.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library; 17 | 18 | import android.annotation.TargetApi; 19 | import android.content.Context; 20 | import android.os.Build.VERSION; 21 | import android.os.Build.VERSION_CODES; 22 | import android.util.AttributeSet; 23 | import android.view.View; 24 | import android.widget.GridView; 25 | 26 | import com.handmark.pulltorefresh.R; 27 | import com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor; 28 | 29 | public class PullToRefreshGridView extends PullToRefreshAdapterViewBase { 30 | 31 | public PullToRefreshGridView(Context context) { 32 | super(context); 33 | } 34 | 35 | public PullToRefreshGridView(Context context, AttributeSet attrs) { 36 | super(context, attrs); 37 | } 38 | 39 | public PullToRefreshGridView(Context context, Mode mode) { 40 | super(context, mode); 41 | } 42 | 43 | public PullToRefreshGridView(Context context, Mode mode, AnimationStyle style) { 44 | super(context, mode, style); 45 | } 46 | 47 | @Override 48 | public final Orientation getPullToRefreshScrollDirection() { 49 | return Orientation.VERTICAL; 50 | } 51 | 52 | @Override 53 | protected final GridView createRefreshableView(Context context, AttributeSet attrs) { 54 | final GridView gv; 55 | if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { 56 | gv = new InternalGridViewSDK9(context, attrs); 57 | } else { 58 | gv = new InternalGridView(context, attrs); 59 | } 60 | 61 | // Use Generated ID (from res/values/ids.xml) 62 | gv.setId(R.id.gridview); 63 | return gv; 64 | } 65 | 66 | class InternalGridView extends GridView implements EmptyViewMethodAccessor { 67 | 68 | public InternalGridView(Context context, AttributeSet attrs) { 69 | super(context, attrs); 70 | } 71 | 72 | @Override 73 | public void setEmptyView(View emptyView) { 74 | PullToRefreshGridView.this.setEmptyView(emptyView); 75 | } 76 | 77 | @Override 78 | public void setEmptyViewInternal(View emptyView) { 79 | super.setEmptyView(emptyView); 80 | } 81 | } 82 | 83 | @TargetApi(9) 84 | final class InternalGridViewSDK9 extends InternalGridView { 85 | 86 | public InternalGridViewSDK9(Context context, AttributeSet attrs) { 87 | super(context, attrs); 88 | } 89 | 90 | @Override 91 | protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, 92 | int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { 93 | 94 | final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, 95 | scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); 96 | 97 | // Does all of the hard work... 98 | OverscrollHelper.overScrollBy(PullToRefreshGridView.this, deltaX, scrollX, deltaY, scrollY, isTouchEvent); 99 | 100 | return returnValue; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshHorizontalScrollView.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library; 17 | 18 | import android.annotation.TargetApi; 19 | import android.content.Context; 20 | import android.os.Build.VERSION; 21 | import android.os.Build.VERSION_CODES; 22 | import android.util.AttributeSet; 23 | import android.view.View; 24 | import android.widget.HorizontalScrollView; 25 | 26 | import com.handmark.pulltorefresh.R; 27 | 28 | public class PullToRefreshHorizontalScrollView extends PullToRefreshBase { 29 | 30 | public PullToRefreshHorizontalScrollView(Context context) { 31 | super(context); 32 | } 33 | 34 | public PullToRefreshHorizontalScrollView(Context context, AttributeSet attrs) { 35 | super(context, attrs); 36 | } 37 | 38 | public PullToRefreshHorizontalScrollView(Context context, Mode mode) { 39 | super(context, mode); 40 | } 41 | 42 | public PullToRefreshHorizontalScrollView(Context context, Mode mode, AnimationStyle style) { 43 | super(context, mode, style); 44 | } 45 | 46 | @Override 47 | public final Orientation getPullToRefreshScrollDirection() { 48 | return Orientation.HORIZONTAL; 49 | } 50 | 51 | @Override 52 | protected HorizontalScrollView createRefreshableView(Context context, AttributeSet attrs) { 53 | HorizontalScrollView scrollView; 54 | 55 | if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { 56 | scrollView = new InternalHorizontalScrollViewSDK9(context, attrs); 57 | } else { 58 | scrollView = new HorizontalScrollView(context, attrs); 59 | } 60 | 61 | scrollView.setId(R.id.scrollview); 62 | return scrollView; 63 | } 64 | 65 | @Override 66 | protected boolean isReadyForPullStart() { 67 | return mRefreshableView.getScrollX() == 0; 68 | } 69 | 70 | @Override 71 | protected boolean isReadyForPullEnd() { 72 | View scrollViewChild = mRefreshableView.getChildAt(0); 73 | if (null != scrollViewChild) { 74 | return mRefreshableView.getScrollX() >= (scrollViewChild.getWidth() - getWidth()); 75 | } 76 | return false; 77 | } 78 | 79 | @TargetApi(9) 80 | final class InternalHorizontalScrollViewSDK9 extends HorizontalScrollView { 81 | 82 | public InternalHorizontalScrollViewSDK9(Context context, AttributeSet attrs) { 83 | super(context, attrs); 84 | } 85 | 86 | @Override 87 | protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, 88 | int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { 89 | 90 | final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, 91 | scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); 92 | 93 | // Does all of the hard work... 94 | OverscrollHelper.overScrollBy(PullToRefreshHorizontalScrollView.this, deltaX, scrollX, deltaY, scrollY, 95 | getScrollRange(), isTouchEvent); 96 | 97 | return returnValue; 98 | } 99 | 100 | /** 101 | * Taken from the AOSP ScrollView source 102 | */ 103 | private int getScrollRange() { 104 | int scrollRange = 0; 105 | if (getChildCount() > 0) { 106 | View child = getChildAt(0); 107 | scrollRange = Math.max(0, child.getWidth() - (getWidth() - getPaddingLeft() - getPaddingRight())); 108 | } 109 | return scrollRange; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshScrollView.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library; 17 | 18 | import android.annotation.TargetApi; 19 | import android.content.Context; 20 | import android.os.Build.VERSION; 21 | import android.os.Build.VERSION_CODES; 22 | import android.util.AttributeSet; 23 | import android.view.View; 24 | import android.widget.ScrollView; 25 | 26 | import com.handmark.pulltorefresh.R; 27 | 28 | public class PullToRefreshScrollView extends PullToRefreshBase { 29 | 30 | public PullToRefreshScrollView(Context context) { 31 | super(context); 32 | } 33 | 34 | public PullToRefreshScrollView(Context context, AttributeSet attrs) { 35 | super(context, attrs); 36 | } 37 | 38 | public PullToRefreshScrollView(Context context, Mode mode) { 39 | super(context, mode); 40 | } 41 | 42 | public PullToRefreshScrollView(Context context, Mode mode, AnimationStyle style) { 43 | super(context, mode, style); 44 | } 45 | 46 | @Override 47 | public final Orientation getPullToRefreshScrollDirection() { 48 | return Orientation.VERTICAL; 49 | } 50 | 51 | @Override 52 | protected ScrollView createRefreshableView(Context context, AttributeSet attrs) { 53 | ScrollView scrollView; 54 | if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { 55 | scrollView = new InternalScrollViewSDK9(context, attrs); 56 | } else { 57 | scrollView = new ScrollView(context, attrs); 58 | } 59 | 60 | scrollView.setId(R.id.scrollview); 61 | return scrollView; 62 | } 63 | 64 | @Override 65 | protected boolean isReadyForPullStart() { 66 | return mRefreshableView.getScrollY() == 0; 67 | } 68 | 69 | @Override 70 | protected boolean isReadyForPullEnd() { 71 | View scrollViewChild = mRefreshableView.getChildAt(0); 72 | if (null != scrollViewChild) { 73 | return mRefreshableView.getScrollY() >= (scrollViewChild.getHeight() - getHeight()); 74 | } 75 | return false; 76 | } 77 | 78 | @TargetApi(9) 79 | final class InternalScrollViewSDK9 extends ScrollView { 80 | 81 | public InternalScrollViewSDK9(Context context, AttributeSet attrs) { 82 | super(context, attrs); 83 | } 84 | 85 | @Override 86 | protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, 87 | int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { 88 | 89 | final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, 90 | scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); 91 | 92 | // Does all of the hard work... 93 | OverscrollHelper.overScrollBy(PullToRefreshScrollView.this, deltaX, scrollX, deltaY, scrollY, 94 | getScrollRange(), isTouchEvent); 95 | 96 | return returnValue; 97 | } 98 | 99 | /** 100 | * Taken from the AOSP ScrollView source 101 | */ 102 | private int getScrollRange() { 103 | int scrollRange = 0; 104 | if (getChildCount() > 0) { 105 | View child = getChildAt(0); 106 | scrollRange = Math.max(0, child.getHeight() - (getHeight() - getPaddingBottom() - getPaddingTop())); 107 | } 108 | return scrollRange; 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/library/extras/PullToRefreshWebView2.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library.extras; 17 | 18 | import java.util.concurrent.atomic.AtomicBoolean; 19 | 20 | import android.content.Context; 21 | import android.util.AttributeSet; 22 | import android.webkit.WebView; 23 | 24 | import com.handmark.pulltorefresh.library.PullToRefreshWebView; 25 | 26 | /** 27 | * An advanced version of {@link PullToRefreshWebView} which delegates the 28 | * triggering of the PullToRefresh gesture to the Javascript running within the 29 | * WebView. This means that you should only use this class if: 30 | *

31 | *

38 | *

39 | *

40 | * The way this call works is that when a PullToRefresh gesture is in action, 41 | * the following Javascript methods will be called: 42 | * isReadyForPullDown() and isReadyForPullUp(), it is 43 | * your job to calculate whether the view is in a state where a PullToRefresh 44 | * can happen, and return the result via the callback mechanism. An example can 45 | * be seen below: 46 | *

47 | * 48 | *

 49 |  * function isReadyForPullDown() {
 50 |  *   var result = ...  // Probably using the .scrollTop DOM attribute
 51 |  *   ptr.isReadyForPullDownResponse(result);
 52 |  * }
 53 |  * 
 54 |  * function isReadyForPullUp() {
 55 |  *   var result = ...  // Probably using the .scrollBottom DOM attribute
 56 |  *   ptr.isReadyForPullUpResponse(result);
 57 |  * }
 58 |  * 
59 | * 60 | * @author Chris Banes 61 | */ 62 | public class PullToRefreshWebView2 extends PullToRefreshWebView { 63 | 64 | static final String JS_INTERFACE_PKG = "ptr"; 65 | static final String DEF_JS_READY_PULL_DOWN_CALL = "javascript:isReadyForPullDown();"; 66 | static final String DEF_JS_READY_PULL_UP_CALL = "javascript:isReadyForPullUp();"; 67 | 68 | public PullToRefreshWebView2(Context context) { 69 | super(context); 70 | } 71 | 72 | public PullToRefreshWebView2(Context context, AttributeSet attrs) { 73 | super(context, attrs); 74 | } 75 | 76 | public PullToRefreshWebView2(Context context, Mode mode) { 77 | super(context, mode); 78 | } 79 | 80 | private JsValueCallback mJsCallback; 81 | private final AtomicBoolean mIsReadyForPullDown = new AtomicBoolean(false); 82 | private final AtomicBoolean mIsReadyForPullUp = new AtomicBoolean(false); 83 | 84 | @Override 85 | protected WebView createRefreshableView(Context context, AttributeSet attrs) { 86 | WebView webView = super.createRefreshableView(context, attrs); 87 | 88 | // Need to add JS Interface so we can get the response back 89 | mJsCallback = new JsValueCallback(); 90 | webView.addJavascriptInterface(mJsCallback, JS_INTERFACE_PKG); 91 | 92 | return webView; 93 | } 94 | 95 | @Override 96 | protected boolean isReadyForPullStart() { 97 | // Call Javascript... 98 | getRefreshableView().loadUrl(DEF_JS_READY_PULL_DOWN_CALL); 99 | 100 | // Response will be given to JsValueCallback, which will update 101 | // mIsReadyForPullDown 102 | 103 | return mIsReadyForPullDown.get(); 104 | } 105 | 106 | @Override 107 | protected boolean isReadyForPullEnd() { 108 | // Call Javascript... 109 | getRefreshableView().loadUrl(DEF_JS_READY_PULL_UP_CALL); 110 | 111 | // Response will be given to JsValueCallback, which will update 112 | // mIsReadyForPullUp 113 | 114 | return mIsReadyForPullUp.get(); 115 | } 116 | 117 | /** 118 | * Used for response from Javascript 119 | * 120 | * @author Chris Banes 121 | */ 122 | final class JsValueCallback { 123 | 124 | public void isReadyForPullUpResponse(boolean response) { 125 | mIsReadyForPullUp.set(response); 126 | } 127 | 128 | public void isReadyForPullDownResponse(boolean response) { 129 | mIsReadyForPullDown.set(response); 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/library/extras/SoundPullEventListener.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library.extras; 17 | 18 | import java.util.HashMap; 19 | 20 | import android.content.Context; 21 | import android.media.MediaPlayer; 22 | import android.view.View; 23 | 24 | import com.handmark.pulltorefresh.library.PullToRefreshBase; 25 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; 26 | import com.handmark.pulltorefresh.library.PullToRefreshBase.State; 27 | 28 | public class SoundPullEventListener implements PullToRefreshBase.OnPullEventListener { 29 | 30 | private final Context mContext; 31 | private final HashMap mSoundMap; 32 | 33 | private MediaPlayer mCurrentMediaPlayer; 34 | 35 | /** 36 | * Constructor 37 | * 38 | * @param context - Context 39 | */ 40 | public SoundPullEventListener(Context context) { 41 | mContext = context; 42 | mSoundMap = new HashMap(); 43 | } 44 | 45 | @Override 46 | public final void onPullEvent(PullToRefreshBase refreshView, State event, Mode direction) { 47 | Integer soundResIdObj = mSoundMap.get(event); 48 | if (null != soundResIdObj) { 49 | playSound(soundResIdObj.intValue()); 50 | } 51 | } 52 | 53 | /** 54 | * Set the Sounds to be played when a Pull Event happens. You specify which 55 | * sound plays for which events by calling this method multiple times for 56 | * each event. 57 | *

58 | * If you've already set a sound for a certain event, and add another sound 59 | * for that event, only the new sound will be played. 60 | * 61 | * @param event - The event for which the sound will be played. 62 | * @param resId - Resource Id of the sound file to be played (e.g. 63 | * R.raw.pull_sound) 64 | */ 65 | public void addSoundEvent(State event, int resId) { 66 | mSoundMap.put(event, resId); 67 | } 68 | 69 | /** 70 | * Clears all of the previously set sounds and events. 71 | */ 72 | public void clearSounds() { 73 | mSoundMap.clear(); 74 | } 75 | 76 | /** 77 | * Gets the current (or last) MediaPlayer instance. 78 | */ 79 | public MediaPlayer getCurrentMediaPlayer() { 80 | return mCurrentMediaPlayer; 81 | } 82 | 83 | private void playSound(int resId) { 84 | // Stop current player, if there's one playing 85 | if (null != mCurrentMediaPlayer) { 86 | mCurrentMediaPlayer.stop(); 87 | mCurrentMediaPlayer.release(); 88 | } 89 | 90 | mCurrentMediaPlayer = MediaPlayer.create(mContext, resId); 91 | if (null != mCurrentMediaPlayer) { 92 | mCurrentMediaPlayer.start(); 93 | } 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/library/internal/EmptyViewMethodAccessor.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library.internal; 17 | 18 | import android.view.View; 19 | 20 | /** 21 | * Interface that allows PullToRefreshBase to hijack the call to 22 | * AdapterView.setEmptyView() 23 | * 24 | * @author chris 25 | */ 26 | public interface EmptyViewMethodAccessor { 27 | 28 | /** 29 | * Calls upto AdapterView.setEmptyView() 30 | * 31 | * @param emptyView - to set as Empty View 32 | */ 33 | public void setEmptyViewInternal(View emptyView); 34 | 35 | /** 36 | * Should call PullToRefreshBase.setEmptyView() which will then 37 | * automatically call through to setEmptyViewInternal() 38 | * 39 | * @param emptyView - to set as Empty View 40 | */ 41 | public void setEmptyView(View emptyView); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/library/internal/RotateLoadingLayout.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library.internal; 17 | 18 | import android.content.Context; 19 | import android.content.res.TypedArray; 20 | import android.graphics.Matrix; 21 | import android.graphics.drawable.Drawable; 22 | import android.view.animation.Animation; 23 | import android.view.animation.RotateAnimation; 24 | import android.widget.ImageView.ScaleType; 25 | 26 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; 27 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation; 28 | import com.handmark.pulltorefresh.R; 29 | 30 | public class RotateLoadingLayout extends LoadingLayout { 31 | 32 | static final int ROTATION_ANIMATION_DURATION = 1200; 33 | 34 | private final Animation mRotateAnimation; 35 | private final Matrix mHeaderImageMatrix; 36 | 37 | private float mRotationPivotX, mRotationPivotY; 38 | 39 | private final boolean mRotateDrawableWhilePulling; 40 | 41 | public RotateLoadingLayout(Context context, Mode mode, Orientation scrollDirection, TypedArray attrs) { 42 | super(context, mode, scrollDirection, attrs); 43 | 44 | mRotateDrawableWhilePulling = attrs.getBoolean(R.styleable.PullToRefresh_ptrRotateDrawableWhilePulling, true); 45 | 46 | mHeaderImage.setScaleType(ScaleType.MATRIX); 47 | mHeaderImageMatrix = new Matrix(); 48 | mHeaderImage.setImageMatrix(mHeaderImageMatrix); 49 | 50 | mRotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 51 | 0.5f); 52 | mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR); 53 | mRotateAnimation.setDuration(ROTATION_ANIMATION_DURATION); 54 | mRotateAnimation.setRepeatCount(Animation.INFINITE); 55 | mRotateAnimation.setRepeatMode(Animation.RESTART); 56 | } 57 | 58 | public void onLoadingDrawableSet(Drawable imageDrawable) { 59 | if (null != imageDrawable) { 60 | mRotationPivotX = Math.round(imageDrawable.getIntrinsicWidth() / 2f); 61 | mRotationPivotY = Math.round(imageDrawable.getIntrinsicHeight() / 2f); 62 | } 63 | } 64 | 65 | protected void onPullImpl(float scaleOfLayout) { 66 | float angle; 67 | if (mRotateDrawableWhilePulling) { 68 | angle = scaleOfLayout * 90f; 69 | } else { 70 | angle = Math.max(0f, Math.min(180f, scaleOfLayout * 360f - 180f)); 71 | } 72 | 73 | mHeaderImageMatrix.setRotate(angle, mRotationPivotX, mRotationPivotY); 74 | mHeaderImage.setImageMatrix(mHeaderImageMatrix); 75 | } 76 | 77 | @Override 78 | protected void refreshingImpl() { 79 | mHeaderImage.startAnimation(mRotateAnimation); 80 | } 81 | 82 | @Override 83 | protected void resetImpl() { 84 | mHeaderImage.clearAnimation(); 85 | resetImageRotation(); 86 | } 87 | 88 | private void resetImageRotation() { 89 | if (null != mHeaderImageMatrix) { 90 | mHeaderImageMatrix.reset(); 91 | mHeaderImage.setImageMatrix(mHeaderImageMatrix); 92 | } 93 | } 94 | 95 | @Override 96 | protected void pullToRefreshImpl() { 97 | // NO-OP 98 | } 99 | 100 | @Override 101 | protected void releaseToRefreshImpl() { 102 | // NO-OP 103 | } 104 | 105 | @Override 106 | protected int getDefaultDrawableResId() { 107 | return R.drawable.default_ptr_rotate; 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/library/internal/Utils.java: -------------------------------------------------------------------------------- 1 | package com.handmark.pulltorefresh.library.internal; 2 | 3 | import android.util.Log; 4 | 5 | public class Utils { 6 | 7 | static final String LOG_TAG = "PullToRefresh"; 8 | 9 | public static void warnDeprecation(String depreacted, String replacement) { 10 | Log.w(LOG_TAG, "You're using the deprecated " + depreacted + " attr, please switch over to " + replacement); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/java/com/handmark/pulltorefresh/library/internal/ViewCompat.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2011, 2012 Chris Banes. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | *******************************************************************************/ 16 | package com.handmark.pulltorefresh.library.internal; 17 | 18 | import android.annotation.TargetApi; 19 | import android.graphics.drawable.Drawable; 20 | import android.os.Build.VERSION; 21 | import android.os.Build.VERSION_CODES; 22 | import android.view.View; 23 | 24 | @SuppressWarnings("deprecation") 25 | public class ViewCompat { 26 | 27 | public static void postOnAnimation(View view, Runnable runnable) { 28 | if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { 29 | SDK16.postOnAnimation(view, runnable); 30 | } else { 31 | view.postDelayed(runnable, 16); 32 | } 33 | } 34 | 35 | public static void setBackground(View view, Drawable background) { 36 | if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { 37 | SDK16.setBackground(view, background); 38 | } else { 39 | view.setBackgroundDrawable(background); 40 | } 41 | } 42 | 43 | public static void setLayerType(View view, int layerType) { 44 | if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) { 45 | SDK11.setLayerType(view, layerType); 46 | } 47 | } 48 | 49 | @TargetApi(11) 50 | static class SDK11 { 51 | 52 | public static void setLayerType(View view, int layerType) { 53 | view.setLayerType(layerType, null); 54 | } 55 | } 56 | 57 | @TargetApi(16) 58 | static class SDK16 { 59 | 60 | public static void postOnAnimation(View view, Runnable runnable) { 61 | view.postOnAnimation(runnable); 62 | } 63 | 64 | public static void setBackground(View view, Drawable background) { 65 | view.setBackground(background); 66 | } 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/anim/slide_in_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/anim/slide_in_from_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/anim/slide_out_to_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/anim/slide_out_to_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/drawable-hdpi/default_ptr_flip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/PullToRefresh/src/main/res/drawable-hdpi/default_ptr_flip.png -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/drawable-hdpi/default_ptr_rotate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/PullToRefresh/src/main/res/drawable-hdpi/default_ptr_rotate.png -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/drawable-hdpi/indicator_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/PullToRefresh/src/main/res/drawable-hdpi/indicator_arrow.png -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/drawable-xhdpi/default_ptr_flip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/PullToRefresh/src/main/res/drawable-xhdpi/default_ptr_flip.png -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/drawable-xhdpi/default_ptr_rotate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/PullToRefresh/src/main/res/drawable-xhdpi/default_ptr_rotate.png -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/drawable-xhdpi/indicator_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/PullToRefresh/src/main/res/drawable-xhdpi/indicator_arrow.png -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/drawable/indicator_bg_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/drawable/indicator_bg_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/layout/pull_to_refresh_header_horizontal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 19 | 20 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/layout/pull_to_refresh_header_vertical.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 17 | 18 | 23 | 24 | 32 | 33 | 34 | 40 | 41 | 48 | 49 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-ar/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | اسحب للتحديث… 4 | اترك للتحديث… 5 | تحميل… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-cs/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Tažením aktualizujete… 4 | Uvolněním aktualizujete… 5 | Načítání… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-de/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Ziehen zum Aktualisieren… 4 | Loslassen zum Aktualisieren… 5 | Laden… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-es/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Tirar para actualizar… 4 | Soltar para actualizar… 5 | Cargando… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-fi/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Päivitä vetämällä alas… 5 | Päivitä vapauttamalla… 6 | Päivitetään… 7 | 8 | 9 | Päivitä vetämällä ylös… 10 | @string/pull_to_refresh_release_label 11 | @string/pull_to_refresh_refreshing_label 12 | 13 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-fr/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Tirez pour rafraîchir… 4 | Relâcher pour rafraîchir… 5 | Chargement… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-he/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | משוך לרענון… 4 | שחרר לרענון… 5 | טוען… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-it/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Tira per aggiornare… 4 | Rilascia per aggionare… 5 | Caricamento… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-iw/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | משוך לרענון… 4 | שחרר לרענון… 5 | טוען… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-ja/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 画面を引っ張って… 4 | 指を離して更新… 5 | 読み込み中… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-ko/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 당겨서 새로 고침… 4 | 놓아서 새로 고침… 5 | 로드 중… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-nl/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sleep om te vernieuwen… 4 | Loslaten om te vernieuwen… 5 | Laden… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-pl/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Pociągnij, aby odświeżyć… 4 | Puść, aby odświeżyć… 5 | Wczytywanie… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-pt-rBR/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Puxe para atualizar… 4 | Libere para atualizar… 5 | Carregando… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-pt/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Puxe para atualizar… 4 | Liberação para atualizar… 5 | A carregar… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-ro/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Trage pentru a reîmprospăta… 4 | Eliberează pentru a reîmprospăta… 5 | Încărcare… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-ru/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Потяните для обновления… 4 | Отпустите для обновления… 5 | Загрузка… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values-zh/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 下拉刷新… 4 | 松开刷新… 5 | 正在载入… 6 | 7 | -------------------------------------------------------------------------------- /PullToRefresh/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 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 66 | 67 | 68 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10dp 5 | 12dp 6 | 4dp 7 | 24dp 8 | 12dp 9 | 10 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /PullToRefresh/src/main/res/values/pull_refresh_strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pull to refresh… 5 | Release to refresh… 6 | Loading… 7 | 8 | 9 | @string/pull_to_refresh_pull_label 10 | @string/pull_to_refresh_release_label 11 | @string/pull_to_refresh_refreshing_label 12 | 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ONE-Unofficial 2 | 3 | [Read in English](https://github.com/Uphie/ONE-Unofficial/wiki/ONE-Unofficial) 4 | 5 | **此项目已停止维护。** 6 | 7 | 非官方版“**一个(ONE)**”,一个比官方版更优秀的版本。 8 | 9 | "一个" 是一个韩寒主编的电子杂志 (**http://wufazhuce.com/**)。 10 | 11 | 刚开始接触到“一个”时,深深地被它简洁漂亮的UI设计所打动,当然最核心的是它的内容,每天一更新的金句、文章、问题、创意设计,很投合现在文艺青年的心理。后来作为读者时间长了以后发现广告越来越多,新版本的UI设计越来越不协调,渐渐有些失望。于是有了DIY的想法,在这个项目中改了小部分UI和功能,剃除了广告。 12 | 13 | 新版的官方ONE已经更新到了3.0以上,与旧版改变很大,“东西”板块已经停止更新,增加一些其他板块,此项目会根据可行性和大家的反馈跟进更新,谢谢! 14 | 15 | 关于Api问题,接口由非授权渠道获取,笔者在微博上告知过亭林镇工作室但未获回应,如有侵权请及时告知,笔者可此项目予以删除。 16 | 17 | 引用的库 18 | ---------- 19 | * [butterknife](https://github.com/JakeWharton/butterknife) 20 | * [fastjson](https://github.com/alibaba/fastjson) 21 | * [android-async-http](https://github.com/loopj/android-async-http) 22 | * [fresco](https://github.com/facebook/fresco) 23 | * [paper](https://github.com/pilgr/Paper) 24 | * [android-PullToRefresh](https://github.com/chrisbanes/Android-PullToRefresh) 25 | 26 | 第三方服务 27 | ----------- 28 | * 友盟统计Sdk 29 | * 友盟用户反馈Sdk 30 | * 友盟自动更新Sdk 31 | * Facebook分享Sdk 32 | 33 | 截图 34 | ----------- 35 | 36 | ![Home](https://github.com/Uphie/ONE-Unofficial/blob/master/Screenshots/screenshot-1.png) 37 | ![Article](https://github.com/Uphie/ONE-Unofficial/blob/master/Screenshots/screenshot-2.png) 38 | 39 | ![Question](https://github.com/Uphie/ONE-Unofficial/blob/master/Screenshots/screenshot-3.png) 40 | ![Thing](https://github.com/Uphie/ONE-Unofficial/blob/master/Screenshots/screenshot-4.png) 41 | 42 | 版本 43 | ---------- 44 | 注:建议使用最新代码编译后再预览,代码会不时小幅更新。 45 | * 2016-2-19,修复了一些bug。目前的主框架逐渐显露出了一些不足,无法满足许多逻辑细节和体验细节。希望大家多多提[issue](https://github.com/Uphie/ONE-Unofficial/issues) :) 46 | 47 | * 2016-2-3,增加了“首页”、“文章”、“问题”、“东西”四部分左滑刷新的功能,对PullToRefresh有轻微修改。下一版本会完善一些细节的地方。 48 | 49 | * 2016-1-26,主要在个人中心增加了“关于”、“分享给好友”、“意见反馈”、“评分”和自动更新功能。下一个版本会增加左滑刷新功能。 50 | 51 | * 2016-1-20,这两天修(zhe)改(teng)了下代码,增加了缓存机制,包括图片缓存和文件缓存,限制了最多只能查看往期7天的内容。 52 | 首次尝试了使用[paper](https://github.com/pilgr/Paper),一个优秀的数据存储库,但一个缺点是paper不能设置过期时间,只好自己判断了。下一个版本会增加意见反馈新功能。 53 | 54 | * 2016-1-8,由于工作的关系有一段时间没有维护了,现在拾了起来。从这版中开始使用日期作为版本名,更改了包名为studio.uphie.one。修复了程序长时间后台运行再打开界面重叠的bug,放弃了双击界面“喜欢”的功能。 55 | 56 | -------------------------------------------------------------------------------- /Screenshots/screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/Screenshots/screenshot-1.png -------------------------------------------------------------------------------- /Screenshots/screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/Screenshots/screenshot-2.png -------------------------------------------------------------------------------- /Screenshots/screenshot-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/Screenshots/screenshot-3.png -------------------------------------------------------------------------------- /Screenshots/screenshot-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/Screenshots/screenshot-4.png -------------------------------------------------------------------------------- /Screenshots/screenshot-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/Screenshots/screenshot-5.png -------------------------------------------------------------------------------- /Screenshots/screenshot-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/Screenshots/screenshot-6.png -------------------------------------------------------------------------------- /Screenshots/screenshot-7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/Screenshots/screenshot-7.jpg -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 22 5 | buildToolsVersion "22.0.1" 6 | 7 | defaultConfig { 8 | applicationId "studio.uphie.one" 9 | minSdkVersion 15 10 | targetSdkVersion 22 11 | versionCode 8 12 | versionName "2016-2-19" 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(include: ['*.jar'], dir: 'libs') 24 | compile project(':PullToRefresh') 25 | compile 'com.android.support:appcompat-v7:22.2.1' 26 | // compile 'com.android.support:support-v4:22+' 27 | compile 'com.loopj.android:android-async-http:1.4.5' 28 | compile 'com.jakewharton:butterknife:7.0.1' 29 | compile 'com.facebook.fresco:fresco:0.8.0+' 30 | compile 'io.paperdb:paperdb:1.1' 31 | //友盟统计 32 | compile 'com.umeng.analytics:analytics:latest.integration' 33 | //facebook 34 | compile 'com.facebook.android:facebook-android-sdk:4.6.0' 35 | compile files('libs/com.umeng.fb.5.4.0.jar') 36 | compile files('libs/umeng-update-v2.6.0.1.jar') 37 | //友盟推送 友盟推送配合用户反馈sdk在小米手机上会有崩溃的情况发生 38 | // compile files('libs/com.umeng.message_v2.7.0.jar') 39 | } 40 | -------------------------------------------------------------------------------- /app/libs/com.umeng.fb.5.4.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/libs/com.umeng.fb.5.4.0.jar -------------------------------------------------------------------------------- /app/libs/fastjson-1.2.6.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/libs/fastjson-1.2.6.jar -------------------------------------------------------------------------------- /app/libs/umeng-update-v2.6.0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/libs/umeng-update-v2.6.0.1.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 E:\AppSoftware\Android SDK/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # 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/studio/uphie/one/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.uphie.one; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | 36 | 37 | 41 | 42 | 47 | 48 | 49 | 52 | 53 | 57 | 58 | 59 | 62 | 63 | 66 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /app/src/main/assets/welcome.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/assets/welcome.gif -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/common/Api.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.common; 2 | 3 | /** 4 | * Created by Uphie on 2015/9/5. 5 | * Email: uphie7@gmail.com 6 | */ 7 | public class Api { 8 | /** 9 | * 首页 10 | */ 11 | public static final String URL_HOME = "http://rest.wufazhuce.com/OneForWeb/one/getHp_N"; 12 | /** 13 | * 文章 14 | */ 15 | public static final String URL_ARTICLE = "http://rest.wufazhuce.com/OneForWeb/one/getC_N"; 16 | /** 17 | * 问题 18 | */ 19 | public static final String URL_QUESTION = "http://rest.wufazhuce.com/OneForWeb/one/getQ_N"; 20 | /** 21 | * 东西 22 | */ 23 | public static final String URL_THING = "http://rest.wufazhuce.com/OneForWeb/one/o_f"; 24 | /** 25 | * 喜欢/取消喜欢 26 | */ 27 | public static final String URL_LIKE_OR_CANCLELIKE = "http://bea.wufazhuce.com/OneForWeb/onest/praiseAppItemSomeId"; 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/common/App.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.common; 2 | 3 | import android.app.Application; 4 | import android.util.DisplayMetrics; 5 | 6 | import com.facebook.FacebookSdk; 7 | import com.umeng.fb.push.FeedbackPush; 8 | 9 | import io.paperdb.Paper; 10 | import studio.uphie.one.utils.ConfigUtil; 11 | import studio.uphie.one.utils.CrashHandler; 12 | import studio.uphie.one.utils.ImageUtil; 13 | import studio.uphie.one.utils.NetworkUtil; 14 | import studio.uphie.one.utils.TextToast; 15 | 16 | /** 17 | * Created by Uphie on 2015/9/5. 18 | * Email: uphie7@gmail.com 19 | */ 20 | public class App extends Application { 21 | 22 | public static DisplayMetrics displayMetrics; 23 | 24 | @Override 25 | public void onCreate() { 26 | super.onCreate(); 27 | Paper.init(this); 28 | 29 | CrashHandler.getInstance().init(this); 30 | ImageUtil.init(this); 31 | NetworkUtil.init(this); 32 | ConfigUtil.init(this); 33 | TextToast.init(this); 34 | 35 | //Facebook分享初始化 36 | FacebookSdk.sdkInitialize(getApplicationContext()); 37 | //友盟意见反馈初始化 38 | FeedbackPush.getInstance(this).init(false); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/common/Constants.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.common; 2 | 3 | /** 4 | * Created by Uphie on 2015/9/6. 5 | * Email: uphie7@gmail.com 6 | */ 7 | public class Constants { 8 | 9 | public static final String KEY_DATE="date"; 10 | public static final String KEY_INDEX="index"; 11 | 12 | public static final String TAG_HOME="HM"; 13 | public static final String TAG_ARTICLE="AR"; 14 | public static final String TAG_QUESTION="QU"; 15 | public static final String TAG_THING="TH"; 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/common/HttpClient.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.common; 2 | 3 | import android.content.Context; 4 | 5 | import com.loopj.android.http.AsyncHttpClient; 6 | import com.loopj.android.http.RequestParams; 7 | import com.loopj.android.http.TextHttpResponseHandler; 8 | 9 | public class HttpClient { 10 | private static Context context; 11 | private static AsyncHttpClient asyncHttpClient = new AsyncHttpClient(); 12 | 13 | public static void init(Context ctx) { 14 | context = ctx; 15 | //最大重连2次 16 | asyncHttpClient.setMaxConnections(2); 17 | } 18 | 19 | public static void postByForm( String url, RequestParams params, TextHttpResponseHandler textHttpResponseHandler) { 20 | asyncHttpClient.post(context, url, params, textHttpResponseHandler); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/common/HttpData.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.common; 2 | 3 | /** 4 | * Created by Uphie on 2015/9/6. 5 | * Email: uphie7@gmail.com 6 | */ 7 | public class HttpData { 8 | public String result; 9 | public String data; 10 | 11 | public HttpData(String result, String data) { 12 | this.result = result == null ? "" : result; 13 | this.data = data == null ? "" : data; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/common/HttpError.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.common; 2 | 3 | /** 4 | * Created by Uphie on 2015/9/5. 5 | * Email: uphie7@gmail.com 6 | */ 7 | public class HttpError { 8 | /** 9 | * 错误码 10 | */ 11 | public int statusCode; 12 | /** 13 | * 原因 14 | */ 15 | public String cause; 16 | /** 17 | * 返回结果 18 | */ 19 | public String response; 20 | 21 | public HttpError() { 22 | 23 | } 24 | 25 | public HttpError(int status, String cause, String response) { 26 | this.statusCode = status; 27 | this.cause = cause; 28 | this.response = response; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/interfaces/IHttp.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.interfaces; 2 | 3 | import com.loopj.android.http.RequestParams; 4 | import studio.uphie.one.common.HttpData; 5 | import studio.uphie.one.common.HttpError; 6 | 7 | /** 8 | * Created by Uphie on 2015/9/5. 9 | * Email: uphie7@gmail.com 10 | */ 11 | public interface IHttp { 12 | 13 | void getHttpData(String url, RequestParams param,HttpData httpData); 14 | 15 | void onDataOk(String url, String data); 16 | 17 | void onDataError(String url, HttpError error); 18 | 19 | void onRestoreData(String url); 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/interfaces/IInit.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.interfaces; 2 | 3 | /** 4 | * Created by Uphie on 2015/9/6. 5 | * Email: uphie7@gmail.com 6 | */ 7 | public interface IInit { 8 | int getLayoutId(); 9 | void init(); 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/interfaces/IShare.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.interfaces; 2 | 3 | /** 4 | * Created by Uphie on 2015/10/30. 5 | * Email: uphie7@gmail.com 6 | */ 7 | public interface IShare { 8 | void share(int channel,Object data); 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/interfaces/OnNetConnChangeListener.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.interfaces; 2 | 3 | /** 4 | * Created by Uphie on 2015/9/5. 5 | * Email: uphie7@gmail.com 6 | */ 7 | public interface OnNetConnChangeListener { 8 | void onNetworkDisconnected(); 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/interfaces/ShareChannel.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.interfaces; 2 | 3 | /** 4 | * Created by Uphie on 2015/10/30. 5 | * Email: uphie7@gmail.com 6 | */ 7 | public interface ShareChannel { 8 | int FACEBOOK = 1; 9 | int TWITTER = 2; 10 | int GOOGLE_PLUS = 3; 11 | int WECHAT = 4; 12 | int WEIBO = 5; 13 | int QQ = 6; 14 | int QZONE = 7; 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/ui/FragmentAdapter.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.ui; 2 | 3 | import android.support.v4.app.FragmentManager; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import studio.uphie.one.abs.AbsBaseFragment; 9 | 10 | /** 11 | * Created by Uphie on 2015/9/6. 12 | * Email: uphie7@gmail.com 13 | */ 14 | public class FragmentAdapter extends android.support.v4.app.FragmentPagerAdapter { 15 | 16 | private List fragmentList; 17 | private boolean canLoadMore = true; 18 | 19 | public FragmentAdapter(FragmentManager fm, List fragmentList) { 20 | super(fm); 21 | this.fragmentList = fragmentList == null ? new ArrayList() : fragmentList; 22 | } 23 | 24 | @Override 25 | public T getItem(int position) { 26 | if (fragmentList.size() > 0 && fragmentList.size() > position) { 27 | return fragmentList.get(position); 28 | } 29 | return null; 30 | } 31 | 32 | @Override 33 | public int getCount() { 34 | return fragmentList.size(); 35 | } 36 | 37 | public boolean canLoadMore() { 38 | return canLoadMore; 39 | } 40 | 41 | /** 42 | * 增加一个Fragment 43 | * 44 | * @param fragment 45 | */ 46 | public void add(T fragment) { 47 | fragmentList.add(fragment); 48 | notifyDataSetChanged(); 49 | } 50 | 51 | /** 52 | * 从Adapter中移除Fragment 53 | * 54 | * @param fragment 要移除的Fragment 55 | */ 56 | public void removeFromAdapter(T fragment) { 57 | fragmentList.remove(fragment); 58 | fragment.onDestroy(); 59 | notifyDataSetChanged(); 60 | canLoadMore = false; 61 | } 62 | 63 | /** 64 | * 删除所有的Fragment 65 | */ 66 | public void removeAll() { 67 | for (AbsBaseFragment f : fragmentList) { 68 | f.onDestroyView(); 69 | f.onDestroy(); 70 | } 71 | fragmentList.clear(); 72 | notifyDataSetChanged(); 73 | } 74 | 75 | /** 76 | * 更新Fragment 77 | * 78 | * @param newFragments 新的Fragment 79 | */ 80 | public void replaceAll(List newFragments) { 81 | removeAll(); 82 | fragmentList.addAll(newFragments); 83 | notifyDataSetChanged(); 84 | canLoadMore=true; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/ui/WelcomeActivity.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.ui; 2 | 3 | import android.content.Intent; 4 | import android.net.Uri; 5 | import android.os.Bundle; 6 | import android.os.Handler; 7 | import android.os.Message; 8 | import android.view.View; 9 | import android.widget.TextView; 10 | 11 | import com.facebook.drawee.backends.pipeline.Fresco; 12 | import com.facebook.drawee.interfaces.DraweeController; 13 | import com.facebook.drawee.view.SimpleDraweeView; 14 | import com.umeng.analytics.AnalyticsConfig; 15 | import com.umeng.analytics.MobclickAgent; 16 | import com.umeng.fb.FeedbackAgent; 17 | import com.umeng.fb.model.UserInfo; 18 | import com.umeng.update.UmengUpdateAgent; 19 | 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | import java.util.Random; 23 | 24 | import studio.uphie.one.R; 25 | import studio.uphie.one.abs.AbsBaseActivity; 26 | import studio.uphie.one.common.HttpError; 27 | 28 | import butterknife.Bind; 29 | import butterknife.ButterKnife; 30 | import studio.uphie.one.utils.SysUtil; 31 | 32 | /** 33 | * Created by Uphie on 2015/10/23. 34 | * Email: uphie7@gmail.com 35 | */ 36 | public class WelcomeActivity extends AbsBaseActivity { 37 | 38 | @Bind(R.id.dv_welcome) 39 | SimpleDraweeView dvWelcome; 40 | @Bind(R.id.text_countdown) 41 | TextView textCountdown; 42 | 43 | private int count = 7; 44 | 45 | @Override 46 | public int getLayoutId() { 47 | return R.layout.activity_welcome; 48 | } 49 | 50 | @Override 51 | public void init() { 52 | DraweeController draweeController = Fresco.newDraweeControllerBuilder().setAutoPlayAnimations(true).setUri(Uri.parse("asset://studio.uphie.one/welcome.gif")).build(); 53 | dvWelcome.setController(draweeController); 54 | 55 | textCountdown.setOnClickListener(new View.OnClickListener() { 56 | @Override 57 | public void onClick(View v) { 58 | //必须移除Message,否则Handler会继续执行,导致空指针异常 59 | handler.removeMessages(0); 60 | startActivity(new Intent(WelcomeActivity.this, MainActivity.class)); 61 | finish(); 62 | } 63 | }); 64 | 65 | handler.sendEmptyMessageDelayed(0, 1000); 66 | } 67 | private Handler handler= new Handler() { 68 | @Override 69 | public void handleMessage(Message msg) { 70 | super.handleMessage(msg); 71 | if (msg.what == 0) { 72 | if (count > 0) { 73 | textCountdown.setText(count + ""); 74 | count--; 75 | sendEmptyMessageDelayed(0,1000); 76 | } else { 77 | startActivity(new Intent(WelcomeActivity.this, MainActivity.class)); 78 | finish(); 79 | } 80 | } 81 | } 82 | }; 83 | 84 | 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/ui/article/Article.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.ui.article; 2 | 3 | /** 4 | * Created by Uphie on 2015/9/6. 5 | * Email: uphie7@gmail.com 6 | */ 7 | public class Article { 8 | //最后更新日期 9 | public String strLastUpdateDate; 10 | //文章对应的网页链接 11 | public String sWebLk; 12 | //由文章生成的图片,做什么的??? 13 | public String wImgUrl; 14 | //阅读数量 15 | public String sRdNum; 16 | //??? 17 | public String strContDayDiffer; 18 | //??? 19 | public String sGW; 20 | //id 21 | public String strContentId; 22 | //上架时间 23 | public String strContMarketTime; 24 | //文章标题 25 | public String strContTitle; 26 | //子标题 27 | public String subTitle; 28 | //文章作者 29 | public String strContAuthor; 30 | //文章内容 31 | public String strContent; 32 | //责任编辑 33 | public String strContAuthorIntroduce; 34 | //喜欢的数量 35 | public String strPraiseNumber; 36 | //作者简介 37 | public String sAuth; 38 | //微博名 39 | public String sWbN; 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/ui/article/ArticleFragment.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.ui.article; 2 | 3 | import android.support.v4.app.Fragment; 4 | 5 | import com.umeng.analytics.MobclickAgent; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import studio.uphie.one.R; 11 | import studio.uphie.one.abs.AbsModuleFragment; 12 | import studio.uphie.one.ui.FragmentAdapter; 13 | import studio.uphie.one.utils.TimeUtil; 14 | 15 | /** 16 | * Created by Uphie on 2015/9/6. 17 | * Email: uphie7@gmail.com 18 | */ 19 | public class ArticleFragment extends AbsModuleFragment { 20 | 21 | private String firstArticleDate; 22 | 23 | @Override 24 | public int getLayoutId() { 25 | return R.layout.fragment_article; 26 | } 27 | 28 | @Override 29 | public void init() { 30 | refresh(); 31 | firstArticleDate = TimeUtil.getDate(); 32 | } 33 | 34 | @Override 35 | public void onResume() { 36 | super.onResume(); 37 | MobclickAgent.onPageStart("ArticlePage"); 38 | //如果首页的日期与当前不符,即数据过期,刷新数据。可能有bug 39 | if (firstArticleDate != null && !firstArticleDate.equals(TimeUtil.getDate())) { 40 | refresh(); 41 | } 42 | } 43 | 44 | @Override 45 | public void onPause() { 46 | super.onPause(); 47 | MobclickAgent.onPageEnd("ArticlePage"); 48 | } 49 | 50 | @Override 51 | public void onPageSelected(int position) { 52 | //当前某一个位置已经被选择了 53 | 54 | //当当前页为viewpager的倒数最后一页时,加载下一页 55 | if (adapter.getCount() == position + 1) { 56 | adapter.add(ArticleContentFragment.newInstance(position + 2)); 57 | } 58 | } 59 | 60 | @Override 61 | public void refresh() { 62 | List list = new ArrayList<>(); 63 | list.add(ArticleContentFragment.newInstance(1)); 64 | list.add(ArticleContentFragment.newInstance(2)); 65 | 66 | adapter = new FragmentAdapter(getChildFragmentManager(), list); 67 | pager.setAdapter(adapter); 68 | // 下面的代码无效,不明原因,换成了上面的两句代码。 69 | // 先移除旧的Fragment后再实例化新的Fragment,adapter更新Fragment,新的Fragment不能实例化。明白的可以与我联系。 70 | // adapter.replaceAll(list); 71 | } 72 | 73 | public Article getCurArticle() { 74 | return ((ArticleContentFragment) adapter.getItem(pager.getCurrentItem())).getContentData(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/ui/home/Home.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.ui.home; 2 | 3 | /** 4 | * Created by Uphie on 2015/9/10. 5 | * Email: uphie7@gmail.com 6 | */ 7 | public class Home { 8 | //最近更新时间 9 | public String strLastUpdateDate; 10 | //??? 11 | public String strDayDiffer; 12 | //id 13 | public String strHpId; 14 | //标题 15 | public String strHpTitle; 16 | //缩略图地址 17 | public String strThumbnailUrl; 18 | //原图地址 19 | public String strOriginalImgUrl; 20 | //作者 21 | public String strAuthor; 22 | //内容 23 | public String strContent; 24 | //上架时间 25 | public String strMarketTime; 26 | //网页版链接 27 | public String sWebLk; 28 | //喜欢的数量 29 | public String strPn; 30 | //原文生成的图片 31 | public String wImgUrl; 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/ui/home/HomeFragment.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.ui.home; 2 | 3 | import com.umeng.analytics.MobclickAgent; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import studio.uphie.one.R; 9 | import studio.uphie.one.abs.AbsBaseFragment; 10 | import studio.uphie.one.abs.AbsModuleFragment; 11 | import studio.uphie.one.ui.FragmentAdapter; 12 | import studio.uphie.one.utils.TimeUtil; 13 | 14 | /** 15 | * Created by Uphie on 2015/9/6. 16 | * Email: uphie7@gmail.com 17 | */ 18 | public class HomeFragment extends AbsModuleFragment { 19 | 20 | private String firstHomeDate; 21 | 22 | @Override 23 | public int getLayoutId() { 24 | return R.layout.fragment_home; 25 | } 26 | 27 | @Override 28 | public void init() { 29 | refresh(); 30 | firstHomeDate = TimeUtil.getDate(); 31 | } 32 | 33 | @Override 34 | public void onResume() { 35 | super.onResume(); 36 | MobclickAgent.onPageStart("HomePage"); 37 | //如果首页的日期与当前不符,即数据过期,刷新数据。可能有bug 38 | if (firstHomeDate != null && !firstHomeDate.equals(TimeUtil.getDate())) { 39 | refresh(); 40 | } 41 | } 42 | 43 | @Override 44 | public void onPause() { 45 | super.onPause(); 46 | MobclickAgent.onPageEnd("HomePage"); 47 | } 48 | 49 | @Override 50 | public void onPageSelected(int position) { 51 | //当前某一个位置已经被选择了 52 | 53 | //当当前页为viewpager的最后一页时,加载下一页 54 | if (adapter.getCount() == position + 1) { 55 | adapter.add(HomeContentFragment.newInstance(position + 2)); 56 | } 57 | } 58 | 59 | @Override 60 | public void refresh() { 61 | //先展示当天的首页 62 | List list = new ArrayList<>(); 63 | list.add(HomeContentFragment.newInstance(1)); 64 | list.add(HomeContentFragment.newInstance(2)); 65 | 66 | adapter = new FragmentAdapter(getChildFragmentManager(), list); 67 | pager.setAdapter(adapter); 68 | 69 | // 下面的代码无效,不明原因,换成了上面的两句代码。 70 | // 先移除旧的Fragment后再实例化新的Fragment,adapter更新Fragment,新的Fragment不能实例化。明白的可以与我联系。 71 | // adapter.replaceAll(list); 72 | } 73 | 74 | public Home getCurSaying() { 75 | return ((HomeContentFragment) adapter.getItem(pager.getCurrentItem())).getContentData(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/ui/personal/AboutActivity.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.ui.personal; 2 | 3 | import android.content.Intent; 4 | import android.net.Uri; 5 | import android.text.SpannableString; 6 | import android.text.Spanned; 7 | import android.text.style.ClickableSpan; 8 | import android.text.style.ForegroundColorSpan; 9 | import android.view.View; 10 | import android.widget.TextView; 11 | 12 | import butterknife.Bind; 13 | import studio.uphie.one.R; 14 | import studio.uphie.one.abs.AbsBaseActivity; 15 | 16 | /** 17 | * Created by Uphie on 2015/10/9. 18 | * Email: uphie7@gmail.com 19 | */ 20 | public class AboutActivity extends AbsBaseActivity { 21 | 22 | @Bind(R.id.text_about) 23 | TextView textAbout; 24 | 25 | @Override 26 | public int getLayoutId() { 27 | return R.layout.activity_about; 28 | } 29 | 30 | @Override 31 | public void init() { 32 | setTitle(R.string.item_about); 33 | 34 | String s = getResources().getString(R.string.content_about); 35 | int start=s.indexOf("『"); 36 | int end=s.indexOf("』")+1; 37 | SpannableString content = new SpannableString(s); 38 | //ClickableSpan会默认给区域内的文件设为下划线、绿色字体 39 | content.setSpan(new ClickableSpan() { 40 | @Override 41 | public void onClick(View widget) { 42 | Intent intent = new Intent(Intent.ACTION_VIEW); 43 | intent.setData(Uri.parse("market://details?id=one.hh.oneclient")); 44 | startActivity(intent); 45 | } 46 | }, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 47 | 48 | //此处将上面的绿色字体覆盖为了蓝色(前景色即为字体的颜色) 49 | content.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.blue)), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 50 | 51 | textAbout.setText(content); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/ui/personal/PersonalFragment.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.ui.personal; 2 | 3 | import android.content.Intent; 4 | import android.net.Uri; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.support.v4.app.Fragment; 8 | import android.util.Log; 9 | import android.view.LayoutInflater; 10 | import android.view.View; 11 | import android.view.ViewGroup; 12 | import android.widget.TextView; 13 | 14 | import com.umeng.analytics.MobclickAgent; 15 | 16 | import butterknife.Bind; 17 | import butterknife.ButterKnife; 18 | import butterknife.OnClick; 19 | import studio.uphie.one.R; 20 | import studio.uphie.one.utils.TextToast; 21 | 22 | /** 23 | * Created by Uphie on 2015/9/6. 24 | * Email: uphie7@gmail.com 25 | */ 26 | public class PersonalFragment extends Fragment { 27 | 28 | @Nullable 29 | @Override 30 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 31 | View view = inflater.inflate(R.layout.fragment_personal, null); 32 | ButterKnife.bind(this, view); 33 | init(); 34 | return view; 35 | } 36 | 37 | private void init() { 38 | } 39 | 40 | @Override 41 | public void onResume() { 42 | super.onResume(); 43 | MobclickAgent.onPageStart("PersonalPage"); 44 | } 45 | 46 | @Override 47 | public void onPause() { 48 | super.onPause(); 49 | MobclickAgent.onPageEnd("PersonalPage"); 50 | } 51 | 52 | @Override 53 | public void onDestroyView() { 54 | super.onDestroyView(); 55 | ButterKnife.unbind(this); 56 | } 57 | 58 | @OnClick({R.id.item_about, R.id.item_share_app, R.id.item_feedback, R.id.item_comment}) 59 | public void onClick(View view) { 60 | Intent intent; 61 | switch (view.getId()) { 62 | case R.id.item_about: 63 | intent = new Intent(getActivity(), AboutActivity.class); 64 | startActivity(intent); 65 | break; 66 | case R.id.item_share_app: 67 | intent = new Intent(Intent.ACTION_SEND); 68 | intent.putExtra(Intent.EXTRA_TEXT, "我发现一个不错的应用,ONE(非官方版),每天给你一个新心情:)\n Github: https://github.com/Uphie/ONE-Unofficial"); 69 | intent.setType("text/plain"); 70 | startActivity(intent); 71 | break; 72 | case R.id.item_feedback: 73 | intent = new Intent(getActivity(), FeedbackActivity.class); 74 | startActivity(intent); 75 | break; 76 | case R.id.item_comment: 77 | //跳转到应用商店,官方ONE的详情页 78 | intent = new Intent(Intent.ACTION_VIEW); 79 | intent.setData(Uri.parse("market://details?id=one.hh.oneclient")); 80 | //必须先检查是否有应用商店安装,否则可能会崩溃 81 | if (intent.resolveActivity(getActivity().getPackageManager()) != null) { 82 | //有应用商店 83 | startActivity(intent); 84 | }else { 85 | //无应用商店 86 | TextToast.longShow(R.string.non_market_app); 87 | } 88 | break; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/ui/question/Question.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.ui.question; 2 | 3 | /** 4 | * Created by Uphie on 2015/10/8. 5 | * Email uphie7@gmail.com 6 | */ 7 | public class Question { 8 | 9 | /** 10 | * ??? 11 | */ 12 | public QNCmt entQNCmt; 13 | /** 14 | * 最近更新时间 15 | */ 16 | public String strLastUpdateDate; 17 | /** 18 | * ??? 19 | */ 20 | public String strDayDiffer; 21 | /** 22 | * 网页版链接 23 | */ 24 | public String sWebLk; 25 | /** 26 | * 喜欢的数量 27 | */ 28 | public int strPraiseNumber; 29 | /** 30 | * 问题id 31 | */ 32 | public int strQuestionId; 33 | /** 34 | * 问题标题 35 | */ 36 | public String strQuestionTitle; 37 | /** 38 | * 问题内容 39 | */ 40 | public String strQuestionContent; 41 | /** 42 | * 回答标题 43 | */ 44 | public String strAnswerTitle; 45 | /** 46 | * 回答内容 47 | */ 48 | public String strAnswerContent; 49 | /** 50 | * 问题上架时间 51 | */ 52 | public String strQuestionMarketTime; 53 | /** 54 | * 编辑 55 | */ 56 | public String sEditor; 57 | 58 | public static class QNCmt { 59 | public String strCnt; 60 | public String strId; 61 | public String strD; 62 | public String pNum; 63 | public String upFg; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/ui/question/QuestionFragment.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.ui.question; 2 | 3 | import android.support.v4.app.Fragment; 4 | 5 | import com.umeng.analytics.MobclickAgent; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import studio.uphie.one.R; 11 | import studio.uphie.one.abs.AbsModuleFragment; 12 | import studio.uphie.one.ui.FragmentAdapter; 13 | import studio.uphie.one.utils.TimeUtil; 14 | 15 | /** 16 | * Created by Uphie on 2015/9/6. 17 | * Email: uphie7@gmail.com 18 | */ 19 | public class QuestionFragment extends AbsModuleFragment { 20 | 21 | private String firstQuestionDate; 22 | 23 | @Override 24 | public int getLayoutId() { 25 | return R.layout.fragment_question; 26 | } 27 | 28 | @Override 29 | public void init() { 30 | refresh(); 31 | firstQuestionDate = TimeUtil.getDate(); 32 | } 33 | 34 | @Override 35 | public void onPageSelected(int position) { 36 | //当当前页为viewpager的最后一页时,加载下一页 37 | if (adapter.getCount() == position + 1) { 38 | adapter.add(QuestionContentFragment.newInstance(position+2)); 39 | } 40 | } 41 | 42 | @Override 43 | public void onResume() { 44 | super.onResume(); 45 | MobclickAgent.onPageStart("QuestionPage"); 46 | //如果首页的日期与当前不符,即数据过期,刷新数据。可能有bug 47 | if (firstQuestionDate != null && !firstQuestionDate.equals(TimeUtil.getDate())) { 48 | refresh(); 49 | } 50 | } 51 | 52 | @Override 53 | public void onPause() { 54 | super.onPause(); 55 | MobclickAgent.onPageEnd("QuestionPage"); 56 | } 57 | 58 | @Override 59 | public void refresh() { 60 | //先展示当天的首页 61 | List list = new ArrayList<>(); 62 | list.add(QuestionContentFragment.newInstance(1)); 63 | list.add(QuestionContentFragment.newInstance(2)); 64 | 65 | adapter = new FragmentAdapter(getChildFragmentManager(), list); 66 | pager.setAdapter(adapter); 67 | // 下面的代码无效,不明原因,换成了上面的两句代码。 68 | // 先移除旧的Fragment后再实例化新的Fragment,adapter更新Fragment,新的Fragment不能实例化。明白的可以与我联系。 69 | // adapter.replaceAll(list); 70 | } 71 | 72 | public Question getCurQuestion() { 73 | return ((QuestionContentFragment) adapter.getItem(pager.getCurrentItem())).getContentData(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/ui/thing/Thing.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.ui.thing; 2 | 3 | /** 4 | * Created by Uphie on 2015/10/8. 5 | * Email: uphie7@gmail.com 6 | */ 7 | public class Thing { 8 | //最近更新时间 9 | public String strLastUpdateDate; 10 | //??? 11 | public String strPn; 12 | //东西图片 13 | public String strBu; 14 | //日期 15 | public String strTm; 16 | //本页对应的网页 17 | public String strWu; 18 | //id 19 | public String strId; 20 | //东西名称 21 | public String strTt; 22 | //东西简介 23 | public String strTc; 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/ui/thing/ThingFragment.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.ui.thing; 2 | 3 | import android.support.v4.app.Fragment; 4 | 5 | import com.umeng.analytics.MobclickAgent; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import studio.uphie.one.R; 11 | import studio.uphie.one.abs.AbsModuleFragment; 12 | import studio.uphie.one.ui.FragmentAdapter; 13 | import studio.uphie.one.utils.TimeUtil; 14 | 15 | /** 16 | * Created by Uphie on 2015/9/6. 17 | * Email: uphie7@gmail.com 18 | */ 19 | public class ThingFragment extends AbsModuleFragment { 20 | 21 | private String firstHomeDate; 22 | 23 | @Override 24 | public int getLayoutId() { 25 | return R.layout.fragment_thing; 26 | } 27 | 28 | @Override 29 | public void init() { 30 | refresh(); 31 | firstHomeDate = TimeUtil.getDate(); 32 | } 33 | 34 | @Override 35 | public void onResume() { 36 | super.onResume(); 37 | MobclickAgent.onPageStart("ThingPage"); 38 | //如果首页的日期与当前不符,即数据过期,刷新数据。可能有bug 39 | if (firstHomeDate != null && !firstHomeDate.equals(TimeUtil.getDate())) { 40 | refresh(); 41 | } 42 | } 43 | 44 | @Override 45 | public void onPause() { 46 | super.onPause(); 47 | MobclickAgent.onPageEnd("ThingPage"); 48 | } 49 | 50 | @Override 51 | public void onPageSelected(int position) { 52 | //当当前页为viewpager的最后一页时,加载下一页 53 | if (adapter.getCount() == position + 1) { 54 | adapter.add(ThingContentFragment.newInstance(position + 2)); 55 | } 56 | } 57 | 58 | @Override 59 | public void refresh() { 60 | List list = new ArrayList<>(); 61 | list.add(ThingContentFragment.newInstance(1)); 62 | list.add(ThingContentFragment.newInstance(2)); 63 | 64 | adapter = new FragmentAdapter(getChildFragmentManager(), list); 65 | pager.setAdapter(adapter); 66 | // 下面的代码无效,不明原因,换成了上面的两句代码。 67 | // 先移除旧的Fragment后再实例化新的Fragment,adapter更新Fragment,新的Fragment不能实例化。明白的可以与我联系。 68 | // adapter.replaceAll(list); 69 | } 70 | 71 | public Thing getCurThing() { 72 | return ((ThingContentFragment) adapter.getItem(pager.getCurrentItem())).getContentData(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/utils/ConfigUtil.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.content.SharedPreferences.Editor; 6 | 7 | import java.util.Arrays; 8 | import java.util.HashSet; 9 | import java.util.Iterator; 10 | import java.util.Set; 11 | 12 | /** 13 | * Created by Uphie on 2015/12/17 0017. 14 | * Email:uphie7@gmail.com 15 | */ 16 | public class ConfigUtil { 17 | 18 | private static Context context; 19 | 20 | public static void init(Context ctx) { 21 | context = ctx; 22 | } 23 | 24 | /** 25 | * 写String到本地 26 | * @param file 存储的文件名 27 | * @param key key 28 | * @param value 结果 29 | */ 30 | public static void writeString(String file, String key, String value) { 31 | Editor editor = context.getSharedPreferences(file, Context.MODE_PRIVATE).edit(); 32 | editor.putString(key, value); 33 | editor.apply(); 34 | } 35 | 36 | /** 37 | * 读取String 38 | * @param file 存储的文件名 39 | * @param key key 40 | * @return 结果 41 | */ 42 | public static String readString(String file, String key) { 43 | SharedPreferences sharedPreferences = context.getSharedPreferences(file, Context.MODE_PRIVATE); 44 | return sharedPreferences.getString(key, ""); 45 | } 46 | /** 47 | * 写boolean配置到本地 48 | * @param file 存储的文件名 49 | * @param key key 50 | * @param value 结果 51 | */ 52 | public static void writeBoolean(String file, String key, boolean value) { 53 | Editor editor = context.getSharedPreferences(file, Context.MODE_PRIVATE).edit(); 54 | editor.putBoolean(key, value); 55 | editor.apply(); 56 | } 57 | 58 | /** 59 | * 读取boolean配置,若没有该配置,则返回true 60 | * @param file 存储的文件名 61 | * @param key key 62 | * @return 结果 63 | */ 64 | public static boolean readBoolean(String file, String key) { 65 | SharedPreferences sharedPreferences = context.getSharedPreferences(file, Context.MODE_PRIVATE); 66 | return sharedPreferences.getBoolean(key, true); 67 | } 68 | 69 | /** 70 | * 写int到本地 71 | * @param file 存储的文件名 72 | * @param key key 73 | * @param value 写入的值 74 | */ 75 | public static void writeInt(String file, String key, int value) { 76 | Editor editor = context.getSharedPreferences(file, Context.MODE_PRIVATE).edit(); 77 | editor.putInt(key, value); 78 | editor.apply(); 79 | } 80 | 81 | /** 82 | * 读取int 83 | * @param file 读取的文件名 84 | * @param key key 85 | * @return 读取的值,若Key对应的值不存在,则返回默认值0 86 | */ 87 | public static int readInt(String file, String key) { 88 | SharedPreferences sharedPreferences = context.getSharedPreferences(file, Context.MODE_PRIVATE); 89 | return sharedPreferences.getInt(key, 0); 90 | } 91 | 92 | /** 93 | * 删除配置 94 | * @param file 配置文件名 95 | */ 96 | public static void removeConfig(String file){ 97 | SharedPreferences sharedPreferences = context.getSharedPreferences(file, Context.MODE_PRIVATE); 98 | sharedPreferences.edit().clear().apply(); 99 | } 100 | } 101 | 102 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/utils/FileManager.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.utils; 2 | 3 | import android.os.Environment; 4 | 5 | import java.io.File; 6 | 7 | /** 8 | * Created by Uphie on 2015/9/10. 9 | * Email: uphie7@gmail.com 10 | */ 11 | public class FileManager { 12 | 13 | public static final String DIR_IMG_CACHE = "img"; 14 | private static String appDir; 15 | 16 | /** 17 | * 获得应用主目录 18 | * 19 | * @return 主目录路径 20 | */ 21 | public static String getAppDir() { 22 | if (appDir == null) { 23 | if (SysUtil.isSdExist()) { 24 | appDir = Environment.getExternalStorageDirectory() 25 | .getAbsolutePath() + "/One"; 26 | } else { 27 | appDir = Environment.getRootDirectory() 28 | .getAbsolutePath() + "/One"; 29 | } 30 | } else { 31 | File file = new File(appDir); 32 | //当appDir存在时,返回false;创建成功时,返回true 33 | file.mkdirs(); 34 | } 35 | return appDir; 36 | } 37 | 38 | /** 39 | * 获得应用log目录 40 | * 41 | * @return log目录 42 | */ 43 | public static File getLogDir() { 44 | String appDir = getAppDir(); 45 | String logDir = appDir + "/log"; 46 | File dir = new File(logDir); 47 | dir.mkdirs(); 48 | return dir; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/utils/ImageUtil.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.utils; 2 | 3 | import android.content.Context; 4 | 5 | import com.facebook.cache.disk.DiskCacheConfig; 6 | import com.facebook.drawee.backends.pipeline.Fresco; 7 | import com.facebook.imagepipeline.core.ImagePipelineConfig; 8 | 9 | import java.io.File; 10 | 11 | /** 12 | * Created by Uphie on 2015/9/10. 13 | * Email: uphie7@gmail.com 14 | */ 15 | public class ImageUtil { 16 | 17 | /** 18 | * 最大图片缓存大小,100M 19 | */ 20 | private static final long MAX_IMG_CACHE_SIZE = 1024 * 1024 * 100; 21 | 22 | public static void init(Context context) { 23 | File cacheDir = new File(FileManager.getAppDir()); 24 | 25 | //Fresco配置和初始化 26 | DiskCacheConfig diskCacheConfig = DiskCacheConfig.newBuilder() 27 | .setBaseDirectoryPath(cacheDir) //缓存文件夹所在的路径 28 | .setBaseDirectoryName(FileManager.DIR_IMG_CACHE) //缓存文件夹名称 29 | .setMaxCacheSize(MAX_IMG_CACHE_SIZE).build(); //最大缓存文件大小,必须设置 30 | ImagePipelineConfig imagePipelineConfig = ImagePipelineConfig.newBuilder(context).setMainDiskCacheConfig(diskCacheConfig).build(); 31 | Fresco.initialize(context, imagePipelineConfig); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/utils/JsonUtil.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.utils; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by Uphie on 2015/9/6. 9 | * Email: uphie7@gmail.com 10 | */ 11 | public class JsonUtil { 12 | /** 13 | * 将任意对象(包括数组、Map等数据结构)转换成json字符串 14 | * @param object 15 | * @return 16 | */ 17 | public static String getJson(Object object){ 18 | return JSON.toJSONString(object); 19 | } 20 | 21 | /** 22 | * 将Json解析成对象 23 | * @param json json字符串 24 | * @param clazz 对象类 25 | * @param 26 | * @return 27 | */ 28 | public static T getEntity(String json, Class clazz) { 29 | return JSON.parseObject(json, clazz); 30 | } 31 | 32 | /** 33 | * 将Json解析成对象数组 34 | * @param json json字符串 35 | * @param clazz 对象类 36 | * @param 37 | * @return 38 | */ 39 | public static List getEntities(String json,Class clazz){ 40 | return JSON.parseArray(json,clazz); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/utils/NetworkUtil.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.utils; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.net.ConnectivityManager; 6 | import android.net.NetworkInfo; 7 | import android.telephony.TelephonyManager; 8 | import android.util.Log; 9 | 10 | /** 11 | * Created by Uphie on 2015/9/5. 12 | * Email: uphie7@gmail.com 13 | */ 14 | public class NetworkUtil { 15 | private static ConnectivityManager conManager; 16 | private static NetworkUtil instance; 17 | private static Context context; 18 | 19 | private NetworkUtil(Context context) { 20 | NetworkUtil.conManager = (ConnectivityManager) context 21 | .getSystemService(Activity.CONNECTIVITY_SERVICE); 22 | } 23 | 24 | public static void init(Context ctx) { 25 | NetworkUtil.context = ctx; 26 | } 27 | 28 | public static NetworkUtil getInstance() { 29 | if (NetworkUtil.instance == null) { 30 | NetworkUtil.instance = new NetworkUtil(context); 31 | } 32 | return NetworkUtil.instance; 33 | } 34 | 35 | /** 36 | * @return boolean 37 | * @description 检测服务端是否连接正常 38 | * @date 2014年11月9日 39 | */ 40 | public boolean checkNetworkAvailable() { 41 | return checkMobileActive() || checkWifiActive(); 42 | } 43 | 44 | /** 45 | * @param context 46 | * @param 47 | * @return 48 | * @description 判断网络是否是漫游 49 | * @date 2014-12-5 50 | * @author 史永飞 51 | */ 52 | public boolean isNetworkRoaming(Context context) { 53 | if (conManager != null) { 54 | NetworkInfo info = conManager.getActiveNetworkInfo(); 55 | if (info != null 56 | && info.getType() == ConnectivityManager.TYPE_MOBILE) { 57 | TelephonyManager tm = (TelephonyManager) context 58 | .getSystemService(Context.TELEPHONY_SERVICE); 59 | if (tm != null && tm.isNetworkRoaming()) { 60 | Log.d("Tag", "network is roaming"); 61 | return true; 62 | } else { 63 | Log.d("Tag", "network is not roaming"); 64 | } 65 | } 66 | } 67 | return false; 68 | } 69 | 70 | /** 71 | * @return boolean 72 | * @description 检测Wifi是否可用 73 | * @date 2014年11月9日 74 | */ 75 | public boolean checkWifiActive() { 76 | return conManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI) 77 | .getState() == NetworkInfo.State.CONNECTED; 78 | } 79 | 80 | /** 81 | * @return boolean 82 | * @description 检测移动网络是否可用 83 | * @date 2014年11月9日 84 | */ 85 | public boolean checkMobileActive() { 86 | return conManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) 87 | .getState() == NetworkInfo.State.CONNECTED; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/utils/SysUtil.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.utils; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.os.Build; 6 | import android.os.Environment; 7 | import android.util.DisplayMetrics; 8 | 9 | /** 10 | * Created by Uphie on 2015/9/6. 11 | * Email: uphie7@gmail.com 12 | */ 13 | public class SysUtil { 14 | 15 | /** 16 | * 获得设备屏幕的相关信息 17 | * 18 | * @param context Activity 19 | * @return 20 | */ 21 | public static DisplayMetrics getDisplayMetrics(Activity context) { 22 | DisplayMetrics displayMetrics = new DisplayMetrics(); 23 | context.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); 24 | return displayMetrics; 25 | } 26 | 27 | /** 28 | * 获得设备型号 29 | * @return 手机设备型号 30 | */ 31 | public static String getPhoneModel(){ 32 | return Build.MODEL; 33 | } 34 | 35 | /** 36 | * 获得设备序列号,但在某些山寨或定制设备上会得到垃圾数据 37 | * @return 手机设备序列号 38 | */ 39 | public static String getPhoneSerial(){ 40 | return Build.SERIAL; 41 | } 42 | 43 | /** 44 | * SD卡是否存在 45 | * 46 | * @return 47 | */ 48 | public static boolean isSdExist() { 49 | return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/utils/TextToast.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.utils; 2 | 3 | import android.content.Context; 4 | import android.view.Gravity; 5 | import android.widget.Toast; 6 | 7 | /** 8 | * Created by Uphie on 2015/9/7. 9 | * Email: uphie7@gmail.com 10 | */ 11 | public class TextToast { 12 | 13 | private static Context context; 14 | 15 | public static void init(Context ctx){ 16 | context=ctx; 17 | } 18 | 19 | public static void shortShow(String content){ 20 | if (context==null){ 21 | throw new IllegalStateException("TextToast was not initialized"); 22 | } 23 | Toast toast= Toast.makeText(context, content, Toast.LENGTH_SHORT); 24 | toast.setGravity(Gravity.CENTER, 0, 0); 25 | toast.show(); 26 | } 27 | public static void shortShow(int resId){ 28 | String content=context.getResources().getString(resId); 29 | if (context==null){ 30 | throw new IllegalStateException("TextToast was not initialized"); 31 | } 32 | Toast toast= Toast.makeText(context, content, Toast.LENGTH_SHORT); 33 | toast.setGravity(Gravity.CENTER, 0, 0); 34 | toast.show(); 35 | } 36 | public static void longShow(String content){ 37 | if (context==null){ 38 | throw new IllegalStateException("TextToast was not initialized"); 39 | } 40 | Toast toast= Toast.makeText(context, content, Toast.LENGTH_LONG); 41 | toast.setGravity(Gravity.CENTER, 0, 0); 42 | toast.show(); 43 | } 44 | public static void longShow(int resId){ 45 | String content=context.getResources().getString(resId); 46 | if (context==null){ 47 | throw new IllegalStateException("TextToast was not initialized"); 48 | } 49 | Toast toast= Toast.makeText(context, content, Toast.LENGTH_LONG); 50 | toast.setGravity(Gravity.CENTER, 0, 0); 51 | toast.show(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/widgets/ClearEditText.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.widgets; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.Drawable; 5 | import android.text.Editable; 6 | import android.text.TextWatcher; 7 | import android.util.AttributeSet; 8 | import android.view.MotionEvent; 9 | import android.view.View; 10 | import android.view.View.OnFocusChangeListener; 11 | import android.view.animation.Animation; 12 | import android.view.animation.CycleInterpolator; 13 | import android.view.animation.TranslateAnimation; 14 | import android.widget.EditText; 15 | 16 | import studio.uphie.one.R; 17 | 18 | public class ClearEditText extends EditText implements 19 | OnFocusChangeListener, TextWatcher { 20 | private Drawable mClearDrawable; 21 | 22 | public ClearEditText(Context context) { 23 | this(context, null); 24 | } 25 | 26 | public ClearEditText(Context context, AttributeSet attrs) { 27 | this(context, attrs, android.R.attr.editTextStyle); 28 | } 29 | 30 | public ClearEditText(Context context, AttributeSet attrs, int defStyle) { 31 | super(context, attrs, defStyle); 32 | init(); 33 | } 34 | 35 | private void init() { 36 | mClearDrawable = getCompoundDrawables()[2]; 37 | if (mClearDrawable == null) { 38 | mClearDrawable = getResources() 39 | .getDrawable(R.drawable.ic_clear); 40 | } 41 | mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight()); 42 | setClearIconVisible(false); 43 | setOnFocusChangeListener(this); 44 | addTextChangedListener(this); 45 | } 46 | @Override 47 | public boolean onTouchEvent(MotionEvent event) { 48 | if (getCompoundDrawables()[2] != null) { 49 | if (event.getAction() == MotionEvent.ACTION_UP) { 50 | boolean touchable = event.getX() > (getWidth() 51 | - getPaddingRight() - mClearDrawable.getIntrinsicWidth()) 52 | && (event.getX() < ((getWidth() - getPaddingRight()))); 53 | if (touchable) { 54 | this.setText(""); 55 | } 56 | } 57 | } 58 | 59 | return super.onTouchEvent(event); 60 | } 61 | @Override 62 | public void onFocusChange(View v, boolean hasFocus) { 63 | if (hasFocus) { 64 | setClearIconVisible(getText().length() > 0); 65 | } else { 66 | setClearIconVisible(false); 67 | } 68 | } 69 | protected void setClearIconVisible(boolean visible) { 70 | Drawable right = visible ? mClearDrawable : null; 71 | setCompoundDrawables(getCompoundDrawables()[0], 72 | getCompoundDrawables()[1], right, getCompoundDrawables()[3]); 73 | } 74 | 75 | @Override 76 | public void onTextChanged(CharSequence s, int start, int count, 77 | int after) { 78 | setClearIconVisible(s.length() > 0); 79 | } 80 | 81 | @Override 82 | public void beforeTextChanged(CharSequence s, int start, int count, 83 | int after) { 84 | 85 | } 86 | 87 | @Override 88 | public void afterTextChanged(Editable s) { 89 | 90 | } 91 | 92 | public void setShakeAnimation(){ 93 | this.setAnimation(shakeAnimation(5)); 94 | } 95 | public static Animation shakeAnimation(int counts){ 96 | Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0); 97 | translateAnimation.setInterpolator(new CycleInterpolator(counts)); 98 | translateAnimation.setDuration(1000); 99 | return translateAnimation; 100 | } 101 | 102 | 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/widgets/LikeView.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.widgets; 2 | 3 | import android.content.Context; 4 | import android.text.TextUtils; 5 | import android.util.AttributeSet; 6 | import android.view.Gravity; 7 | import android.widget.CheckBox; 8 | import android.widget.CheckedTextView; 9 | import android.widget.CompoundButton; 10 | import android.widget.TextView; 11 | 12 | import studio.uphie.one.R; 13 | 14 | /** 15 | * Created by Uphie on 2015/9/11. 16 | * Email: uphie7@gmail.com 17 | */ 18 | public class LikeView extends CheckBox implements CompoundButton.OnCheckedChangeListener { 19 | 20 | private int likeCount; 21 | private OnLikeChangedListener onLikeChangedListener; 22 | 23 | public LikeView(Context context, AttributeSet attrs) { 24 | super(context, attrs); 25 | init(); 26 | } 27 | 28 | private void init() { 29 | setGravity(Gravity.CENTER_VERTICAL); 30 | refresh(isChecked()); 31 | String text = getText().toString().trim(); 32 | if (TextUtils.isEmpty(text)) { 33 | likeCount = 0; 34 | } else { 35 | likeCount = Integer.parseInt(text); 36 | } 37 | setText(likeCount + ""); 38 | 39 | setOnCheckedChangeListener(this); 40 | } 41 | 42 | private void refresh(boolean checked) { 43 | String text = getText().toString().trim(); 44 | if (TextUtils.isEmpty(text)) { 45 | likeCount = 0; 46 | } else { 47 | likeCount = Integer.parseInt(text); 48 | } 49 | if (checked) { 50 | setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_liked), null, null, null); 51 | likeCount++; 52 | setText(likeCount + ""); 53 | } else { 54 | setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_like), null, null, null); 55 | if (likeCount > 0) { 56 | likeCount--; 57 | } 58 | setText(likeCount + ""); 59 | } 60 | } 61 | 62 | public void addOnLikeChangeListener(OnLikeChangedListener onLikeChangedListener) { 63 | this.onLikeChangedListener = onLikeChangedListener; 64 | } 65 | 66 | public int getLikeCount(){ 67 | return likeCount; 68 | } 69 | 70 | @Override 71 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 72 | refresh(isChecked); 73 | if (onLikeChangedListener != null) { 74 | onLikeChangedListener.onLikeChanged(); 75 | } 76 | } 77 | 78 | public interface OnLikeChangedListener { 79 | void onLikeChanged(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/studio/uphie/one/widgets/Tab.java: -------------------------------------------------------------------------------- 1 | package studio.uphie.one.widgets; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Canvas; 6 | import android.graphics.drawable.Drawable; 7 | import android.util.AttributeSet; 8 | import android.view.Gravity; 9 | import android.widget.RadioButton; 10 | 11 | import studio.uphie.one.R; 12 | 13 | public class Tab extends RadioButton { 14 | /** 15 | * 选择的背景资源id 16 | */ 17 | private int selectedBackground; 18 | /** 19 | * 未选择的背景资源id 20 | */ 21 | private int unselectedBackground; 22 | /** 23 | * 选择的文字颜色资源id 24 | */ 25 | private int selectedTextColor; 26 | /** 27 | * 未选择的文字颜色资源id 28 | */ 29 | private int unselectedTextColor; 30 | 31 | public Tab(Context context, AttributeSet attrs) { 32 | super(context, attrs); 33 | 34 | TypedArray array = context.obtainStyledAttributes(attrs, 35 | R.styleable.Tab); 36 | 37 | selectedBackground = array.getResourceId(R.styleable.Tab_checkedBackground, -1); 38 | unselectedBackground = array.getResourceId(R.styleable.Tab_uncheckedBackground, -1); 39 | 40 | selectedTextColor = array.getResourceId(R.styleable.Tab_checkedTextColor, android.R.color.holo_blue_light); 41 | unselectedTextColor = array.getResourceId(R.styleable.Tab_uncheckedTextColor, android.R.color.black); 42 | 43 | array.recycle(); 44 | 45 | setButtonDrawable(getResources().getDrawable(android.R.color.transparent)); 46 | setGravity(Gravity.CENTER_HORIZONTAL); 47 | setCompoundDrawablePadding(10); 48 | } 49 | 50 | @Override 51 | protected void onDraw(Canvas canvas) { 52 | if (isChecked()) { 53 | setTextColor(getResources().getColor(selectedTextColor)); 54 | if (selectedBackground > 0) { 55 | Drawable selectedDrawable = getResources().getDrawable(selectedBackground); 56 | setCompoundDrawablesWithIntrinsicBounds(null, selectedDrawable, null, null); 57 | } else { 58 | setCompoundDrawablesWithIntrinsicBounds(null, null, null, null); 59 | } 60 | } else { 61 | setTextColor(getResources().getColor(unselectedTextColor)); 62 | if (unselectedBackground > 0) { 63 | Drawable unselectedDrawable = getResources().getDrawable(unselectedBackground); 64 | setCompoundDrawablesWithIntrinsicBounds(null, unselectedDrawable, null, null); 65 | } else { 66 | setCompoundDrawablesWithIntrinsicBounds(null, null, null, null); 67 | } 68 | } 69 | super.onDraw(canvas); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/bg_home_saying.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/bg_home_saying.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/bg_msg_left_highlighted.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/bg_msg_left_highlighted.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/bg_msg_left_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/bg_msg_left_normal.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/bg_msg_right_highlighted.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/bg_msg_right_highlighted.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/bg_msg_right_normal.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/bg_msg_right_normal.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_answer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/ic_answer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_avatar_default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/ic_avatar_default.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/ic_back.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_like.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/ic_like.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_liked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/ic_liked.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/ic_more.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/ic_question.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/ic_title.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_to.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-hdpi/ic_to.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_msg_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-xhdpi/ic_msg_fail.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-xhdpi/logo_facebook.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_google_plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-xhdpi/logo_google_plus.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-xhdpi/logo_qq.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_qzone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-xhdpi/logo_qzone.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_sinaweibo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-xhdpi/logo_sinaweibo.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-xhdpi/logo_twitter.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-xhdpi/logo_wechat.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/av_author.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-xxhdpi/av_author.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Uphie/ONE-Unofficial/ee6dafe2d8f31d3ed1524ae8c425e447502b742b/app/src/main/res/drawable-xxhdpi/ic_clear.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/actionbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_bottom_line_blue.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_bottom_line_gray.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_bottom_line_gray_slim.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_frame_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_top_line.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/checkbox_like.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/divider_light_gray.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/picture_holder.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_edittext.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_msg_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_msg_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_ok_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_text_send.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/share_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_common_gradient_orange.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/umeng_common_gradient_red.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/actionbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 19 | 20 | 27 | 28 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/actionbar_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/actionbar_secondary.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 18 | 19 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_about.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_feedback.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 18 | 19 | 27 | 28 | 41 | 42 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 20 | 21 | 29 | 30 | 31 | 36 | 37 | 44 | 45 | 50 | 51 | 55 | 56 | 60 | 61 | 65 | 66 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_welcome.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 19 | 20 | 28 | 29 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_update.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 25 | 26 | 30 | 31 | 40 | 41 | 50 | 51 | -------------------------------------------------------------------------------- /app/src/main/res/layout/divider_gray_line.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_article.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_personal.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | 12 | 16 | 17 | 21 | 22 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_question.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_thing.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_article.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 20 | 21 | 22 | 23 | 33 | 34 | 42 | 43 | 53 | 54 | 62 | 63 | 66 | 67 | 73 | 74 | 79 | 80 | 87 | 88 | 95 | 96 | 97 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 16 | 22 | 23 | 24 | 25 | 30 | 31 | 41 | 42 | 47 | 48 | 52 | 53 | 61 | 62 | 69 | 70 | 71 | 82 | 83 | 84 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_question.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 19 | 20 | 21 | 22 | 35 | 36 | 42 | 43 | 49 | 50 | 61 | 62 | 67 | 68 | 73 | 74 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_thing.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 14 | 15 | 20 | 21 | 22 | 23 | 29 | 30 | 40 | 41 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_conversion_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 25 | 26 | 32 | 33 | 44 | 45 | 51 | 52 | 59 | 60 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_conversion_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 | 26 | 27 | 34 | 35 | 41 | 42 | 55 | 56 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /app/src/main/res/layout/loading_window.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/menu_share.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 20 | 21 | 26 | 27 | 32 | 33 | 38 | 39 | 44 | 45 | 46 | 47 | 53 | 54 | 59 | 60 | 65 | 66 | 71 | 72 | 73 | 77 | 78 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /app/src/main/res/layout/umeng_common_download_notification.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 19 | 20 | 26 | 27 | 28 | 34 | 35 | 45 | 46 |