From d90e5f12844604c28ef2ef3eea30c7438416343e Mon Sep 17 00:00:00 2001 From: Bai-Jie Date: Tue, 24 Feb 2015 19:28:58 +0800 Subject: [PATCH 001/120] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=E5=88=B01.1.0-SNAPSHOT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index dccd49b..ef5496f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,4 +17,4 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true PROJECTS_GROUP=com.optimalorange.cooltechnologies -VERSION_NAME=1.0.0-SNAPSHOT +VERSION_NAME=1.1.0-SNAPSHOT From 6c7a77fb5a0b06e81bcf4b60d60bb8c791ac9c18 Mon Sep 17 00:00:00 2001 From: Bai-Jie Date: Tue, 24 Feb 2015 20:40:37 +0800 Subject: [PATCH 002/120] =?UTF-8?q?=E4=BD=BF=E7=94=A8com.android.support:a?= =?UTF-8?q?ppcompat-v7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 1 + .../network/NetworkChecker.java | 6 ++--- .../cooltechnologies/ui/BaseActivity.java | 6 ++--- .../ui/ListVideosActivity.java | 2 +- .../cooltechnologies/ui/MainActivity.java | 8 +++--- .../ui/PlayVideoActivity.java | 10 +++---- .../cooltechnologies/ui/SearchActivity.java | 5 ++-- .../ui/fragment/CreateCommentFragment.java | 2 +- .../ui/fragment/HistoryFragment.java | 2 +- .../ui/fragment/ListCommentsFragment.java | 11 ++++---- .../ui/fragment/ListGenresFragment.java | 2 +- .../ui/fragment/ListVideosFragment.java | 5 ++-- .../ui/fragment/PromotionFragment.java | 2 +- .../ui/fragment/SwipeRefreshFragment.java | 2 +- .../cooltechnologies/util/LruBitmapCache.java | 2 +- app/src/main/res/menu/menu_base.xml | 3 ++- .../main/res/menu/menu_login_or_logout.xml | 3 ++- app/src/main/res/menu/menu_refresh.xml | 3 ++- app/src/main/res/menu/menu_search.xml | 7 ++--- app/src/main/res/values-v21/styles.xml | 15 ----------- app/src/main/res/values/styles.xml | 26 +++++++++++++------ 21 files changed, 63 insertions(+), 60 deletions(-) delete mode 100644 app/src/main/res/values-v21/styles.xml diff --git a/app/build.gradle b/app/build.gradle index 7ccac0c..9b5ac56 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -71,6 +71,7 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:support-v4:21.0.3' + compile 'com.android.support:appcompat-v7:21.0.3' compile 'com.android.support:cardview-v7:21.0.3' compile 'com.android.support:recyclerview-v7:21.0.3' compile 'com.android.support:support-v13:21.0.3' diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/network/NetworkChecker.java b/app/src/main/java/com/optimalorange/cooltechnologies/network/NetworkChecker.java index 4f1027d..a914464 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/network/NetworkChecker.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/network/NetworkChecker.java @@ -4,14 +4,14 @@ import android.app.AlertDialog; import android.app.Dialog; -import android.app.DialogFragment; -import android.app.FragmentManager; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.FragmentManager; /** * 网络连接检查器。
可以用它判断能否建立网络连接,{@link ConnectivityManager#TYPE_WIFI WiFi}等网络是否可用。 @@ -22,7 +22,7 @@ public class NetworkChecker { private final ConnectivityManager mConnectivityManager; /** - * {@link #openNoConnectionDialog(android.app.FragmentManager)}打开的{@link DialogFragment}的tag + * {@link #openNoConnectionDialog(FragmentManager)}打开的{@link DialogFragment}的tag */ public static final String FRAGMENT_TAG_NO_CONNECTION_DIALOG = NetworkChecker.class.getName() + ".fragment_tag_no_connection_dialog"; diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/BaseActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/BaseActivity.java index 99aec80..1ea09a7 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/BaseActivity.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/BaseActivity.java @@ -3,15 +3,15 @@ import com.optimalorange.cooltechnologies.R; import com.umeng.analytics.MobclickAgent; -import android.app.Activity; import android.content.Intent; +import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; /** - * 本应用所有{@link Activity}的父类。 + * 本应用所有{@link android.app.Activity Activity}的父类。 */ -public abstract class BaseActivity extends Activity { +public abstract class BaseActivity extends ActionBarActivity { private boolean mShowSettingsMenuItem = true; diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/ListVideosActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/ListVideosActivity.java index 31e0470..f4511eb 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/ListVideosActivity.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/ListVideosActivity.java @@ -34,7 +34,7 @@ protected void onCreate(Bundle savedInstanceState) { } // 添加videosFragment if (savedInstanceState == null) { - getFragmentManager().beginTransaction() + getSupportFragmentManager().beginTransaction() .add(R.id.container, videosFragment) .commit(); } diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/MainActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/MainActivity.java index 6266990..9bc0b3c 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/MainActivity.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/MainActivity.java @@ -11,13 +11,13 @@ import com.umeng.update.UmengUpdateAgent; import com.viewpagerindicator.TitlePageIndicator; -import android.app.Fragment; -import android.app.FragmentManager; import android.content.Context; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.NonNull; -import android.support.v13.app.FragmentPagerAdapter; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.util.Log; import android.view.ViewGroup; @@ -77,7 +77,7 @@ protected void onCreate(Bundle savedInstanceState) { mAdapter = new MyFragmentPagerAdapter( this, - getFragmentManager(), + getSupportFragmentManager(), FRAGMENT_IDS_ORDER_BY_POSITION ); mPager = (ViewPager) findViewById(R.id.pager); diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/PlayVideoActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/PlayVideoActivity.java index 126f4db..e6d7bca 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/PlayVideoActivity.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/PlayVideoActivity.java @@ -161,8 +161,8 @@ public void toggledFullscreen(boolean fullscreen) { //noinspection all getWindow().getDecorView() .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); - if (getActionBar() != null) { - getActionBar().hide(); + if (getSupportActionBar() != null) { + getSupportActionBar().hide(); } setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } else { @@ -173,8 +173,8 @@ public void toggledFullscreen(boolean fullscreen) { //noinspection all getWindow().getDecorView() .setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); - if (getActionBar() != null) { - getActionBar().show(); + if (getSupportActionBar() != null) { + getSupportActionBar().show(); } setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } @@ -289,7 +289,7 @@ private void addWebViewToNonVideoLayout() { private void addOthersToNonVideoLayout(Bundle savedInstanceState) { if (savedInstanceState == null) { - getFragmentManager().beginTransaction() + getSupportFragmentManager().beginTransaction() .add(R.id.others_container, ListCommentsFragment.newInstance(getVideoId())) .commit(); } diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/SearchActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/SearchActivity.java index 466d42a..f337a21 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/SearchActivity.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/SearchActivity.java @@ -16,6 +16,8 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.support.v4.view.MenuItemCompat; +import android.support.v7.widget.SearchView; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -24,7 +26,6 @@ import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ImageView; -import android.widget.SearchView; import android.widget.TextView; import java.util.LinkedList; @@ -151,7 +152,7 @@ public boolean onCreateOptionsMenu(Menu menu) { SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = - (SearchView) menu.findItem(R.id.action_search).getActionView(); + (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search)); searchView.setSearchableInfo( searchManager.getSearchableInfo(getComponentName())); diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/CreateCommentFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/CreateCommentFragment.java index 715b3df..2b2e346 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/CreateCommentFragment.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/CreateCommentFragment.java @@ -9,8 +9,8 @@ import android.app.AlertDialog; import android.app.Dialog; -import android.app.DialogFragment; import android.os.Bundle; +import android.support.v4.app.DialogFragment; import android.view.LayoutInflater; import android.view.View; import android.widget.EditText; diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/HistoryFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/HistoryFragment.java index 183a0f2..54af42d 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/HistoryFragment.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/HistoryFragment.java @@ -8,11 +8,11 @@ import com.optimalorange.cooltechnologies.network.VolleySingleton; import com.umeng.analytics.MobclickAgent; -import android.app.Fragment; import android.content.Context; import android.content.Intent; import android.graphics.PixelFormat; import android.os.Bundle; +import android.support.v4.app.Fragment; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListCommentsFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListCommentsFragment.java index 32e9243..a5c4965 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListCommentsFragment.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListCommentsFragment.java @@ -20,8 +20,6 @@ import android.app.AlertDialog; import android.app.Dialog; -import android.app.DialogFragment; -import android.app.Fragment; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; @@ -30,6 +28,8 @@ import android.net.ConnectivityManager; import android.net.Uri; import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.DialogFragment; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -318,7 +318,7 @@ public void onClick(View view) { if (!mDefaultSharedPreferencesSingleton.hasLoggedIn()) { ToLoginDialogFragment mDialog = ToLoginDialogFragment .newInstance(getString(R.string.create_favorite_to_login_message)); - mDialog.show(getFragmentManager(), null); + mDialog.show(getChildFragmentManager(), null); } else { if (mFavoriteView.isActivated()) { mVolleySingleton.addToRequestQueue(buildDestroyFavoriteRequest(token)); @@ -342,7 +342,7 @@ public void onClick(View view) { } ToLoginDialogFragment mDialog = ToLoginDialogFragment .newInstance(getString(R.string.comment_to_login_message)); - mDialog.show(getFragmentManager(), null); + mDialog.show(getChildFragmentManager(), null); } else { CreateCommentFragment mCreateCommentFragment = CreateCommentFragment .newInstance(mVideoID, token, mContent); @@ -373,7 +373,7 @@ public void onCreateComment(boolean isSuccess) { } }); mCreateCommentFragment - .show(getFragmentManager(), CreateCommentFragment.class.getName()); + .show(getChildFragmentManager(), CreateCommentFragment.class.getName()); } } }); @@ -455,6 +455,7 @@ private void applyVideos() { } } + //TODO 为何禁止super.onCreateOptionsMenu运行? @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { } diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListGenresFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListGenresFragment.java index b846fab..ca72020 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListGenresFragment.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListGenresFragment.java @@ -27,9 +27,9 @@ import android.content.res.Resources; import android.net.ConnectivityManager; import android.os.Bundle; +import android.support.v4.util.Pair; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListVideosFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListVideosFragment.java index 31b3ff6..28ab194 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListVideosFragment.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListVideosFragment.java @@ -23,6 +23,8 @@ import android.net.ConnectivityManager; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.v4.view.MenuItemCompat; +import android.support.v7.widget.SearchView; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -31,7 +33,6 @@ import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ImageView; -import android.widget.SearchView; import android.widget.TextView; import java.util.LinkedList; @@ -340,7 +341,7 @@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE); SearchView searchView = - (SearchView) menu.findItem(R.id.action_search).getActionView(); + (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search)); searchView.setSearchableInfo( searchManager.getSearchableInfo(getActivity().getComponentName())); diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/PromotionFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/PromotionFragment.java index 51bd8b1..989a820 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/PromotionFragment.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/PromotionFragment.java @@ -3,8 +3,8 @@ import com.optimalorange.cooltechnologies.R; import com.umeng.analytics.MobclickAgent; -import android.app.Fragment; import android.os.Bundle; +import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/SwipeRefreshFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/SwipeRefreshFragment.java index 6fcc041..1eda8a5 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/SwipeRefreshFragment.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/SwipeRefreshFragment.java @@ -2,9 +2,9 @@ import com.optimalorange.cooltechnologies.R; -import android.app.Fragment; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; import android.support.v4.widget.SwipeRefreshLayout; import android.view.LayoutInflater; import android.view.Menu; diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/util/LruBitmapCache.java b/app/src/main/java/com/optimalorange/cooltechnologies/util/LruBitmapCache.java index e64b1b7..69e611c 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/util/LruBitmapCache.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/util/LruBitmapCache.java @@ -20,8 +20,8 @@ import android.content.Context; import android.graphics.Bitmap; +import android.support.v4.util.LruCache; import android.util.DisplayMetrics; -import android.util.LruCache; public class LruBitmapCache extends LruCache implements ImageLoader.ImageCache { diff --git a/app/src/main/res/menu/menu_base.xml b/app/src/main/res/menu/menu_base.xml index df058d1..990ed2d 100644 --- a/app/src/main/res/menu/menu_base.xml +++ b/app/src/main/res/menu/menu_base.xml @@ -2,6 +2,7 @@ @@ -10,7 +11,7 @@ android:title="@string/action_settings" android:menuCategory="container" android:orderInCategory="100" - android:showAsAction="never" + app:showAsAction="never" /> diff --git a/app/src/main/res/menu/menu_login_or_logout.xml b/app/src/main/res/menu/menu_login_or_logout.xml index 7ed8c0c..e104618 100644 --- a/app/src/main/res/menu/menu_login_or_logout.xml +++ b/app/src/main/res/menu/menu_login_or_logout.xml @@ -1,12 +1,13 @@ diff --git a/app/src/main/res/menu/menu_refresh.xml b/app/src/main/res/menu/menu_refresh.xml index dd07f66..e6dfc90 100644 --- a/app/src/main/res/menu/menu_refresh.xml +++ b/app/src/main/res/menu/menu_refresh.xml @@ -2,6 +2,7 @@ @@ -10,7 +11,7 @@ android:title="@string/action_refresh" android:icon="@drawable/ic_refresh_white_24dp" android:orderInCategory="100" - android:showAsAction="ifRoom" + app:showAsAction="ifRoom" /> diff --git a/app/src/main/res/menu/menu_search.xml b/app/src/main/res/menu/menu_search.xml index 24640df..815076f 100644 --- a/app/src/main/res/menu/menu_search.xml +++ b/app/src/main/res/menu/menu_search.xml @@ -1,8 +1,9 @@ - + + app:showAsAction="collapseActionView|ifRoom" + app:actionViewClass="android.support.v7.widget.SearchView"/> diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml deleted file mode 100644 index f615ea7..0000000 --- a/app/src/main/res/values-v21/styles.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 5f78f19..a9d49b1 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,19 +1,29 @@ - - - - - + + + + @@ -31,11 +32,11 @@ + From aa0bfa8136724a006eb3460939a3e9287ddd5d5a Mon Sep 17 00:00:00 2001 From: Bai Jie Date: Fri, 5 Jun 2015 16:31:23 +0800 Subject: [PATCH 025/120] =?UTF-8?q?=E6=92=A4=E9=94=80=E6=97=A7=E7=9A=84qui?= =?UTF-8?q?ck=20return=E5=AE=9E=E7=8E=B0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert "完善HistoryFragment" Revert "进一步模块化自动隐藏ActionBar相关实现代码" Revert "删除PMD报告的Useless parentheses" Revert "仅当被Attached到MainActivity时,才对Padding做特殊设置" Revert "初步实现自动隐藏ActionBar(又叫quick return)" This reverts commit 19dff5a5408071c9c418062b1d5e79ea0f3e59b5. This reverts commit 42f8f3d56bd1845f6ce32eb976cd469ebc1baf2c. This reverts commit b8ee16e34f1591ae56e1c3846fc1d691e9fd59b1. This reverts commit 438da7065c402ec23cb994e45a1c222ef5834613. This reverts commit 90814065be3b33669510e90320672b54f798397a. Conflicts: app/src/main/java/com/optimalorange/cooltechnologies/ui/BaseActivity.java app/src/main/res/values/styles.xml --- .../com.google.samples.apps.iosched.LICENSE | 6 +- app/src/main/assets/licenses.html | 8 +- .../cooltechnologies/ui/BaseActivity.java | 168 +----------------- .../cooltechnologies/ui/MainActivity.java | 27 --- .../ui/fragment/HistoryFragment.java | 32 ++-- .../ui/fragment/SwipeRefreshFragment.java | 7 - .../ui/view/AutoHideActionBar.aj | 138 -------------- app/src/main/res/layout/activity_main.xml | 34 ++-- .../main/res/layout/fragment_promotion.xml | 1 - app/src/main/res/values-land/dimens.xml | 6 - app/src/main/res/values-sw600dp/dimens.xml | 6 - app/src/main/res/values/dimens.xml | 18 +- app/src/main/res/values/styles.xml | 9 +- 13 files changed, 35 insertions(+), 425 deletions(-) delete mode 100644 app/src/main/java/com/optimalorange/cooltechnologies/ui/view/AutoHideActionBar.aj delete mode 100644 app/src/main/res/values-land/dimens.xml delete mode 100644 app/src/main/res/values-sw600dp/dimens.xml diff --git a/app/libs/licenses/com.google.samples.apps.iosched.LICENSE b/app/libs/licenses/com.google.samples.apps.iosched.LICENSE index 8466a75..dd16aee 100644 --- a/app/libs/licenses/com.google.samples.apps.iosched.LICENSE +++ b/app/libs/licenses/com.google.samples.apps.iosched.LICENSE @@ -1,10 +1,6 @@ -Some code is taken from Google's iosched(https://github.com/google/iosched) -Such as : +Notice for : BaseActivity.setContentView(int layoutResID) BaseActivity.sgetActionBarToolbar() - BaseActivity.updateSwipeRefreshProgressBarTop() - BaseActivity.onMainContentScrolled(int currentY, int deltaY) - BaseActivity.autoShowOrHideActionBar(boolean show) ------------------------------------------------------------ diff --git a/app/src/main/assets/licenses.html b/app/src/main/assets/licenses.html index 96ae6f4..f92eb79 100644 --- a/app/src/main/assets/licenses.html +++ b/app/src/main/assets/licenses.html @@ -546,16 +546,12 @@

Notice for:

Notice for:

-

Some code is taken from Google's iosched - (https://github.com/google/iosched)
- Such as:

  • BaseActivity.setContentView(int layoutResID)
  • BaseActivity.sgetActionBarToolbar()
  • -
  • BaseActivity.updateSwipeRefreshProgressBarTop()
  • -
  • BaseActivity.onMainContentScrolled(int currentY, int deltaY)
  • -
  • BaseActivity.autoShowOrHideActionBar(boolean show)
+from + https://github.com/google/iosched
 Copyright 2014 Google Inc. All rights reserved.
 
diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/BaseActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/BaseActivity.java
index 4548ba3..3d44dd0 100644
--- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/BaseActivity.java
+++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/BaseActivity.java
@@ -4,80 +4,20 @@
 import com.umeng.analytics.MobclickAgent;
 
 import android.content.Intent;
-import android.support.v4.widget.SwipeRefreshLayout;
 import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.Toolbar;
 import android.view.Menu;
 import android.view.MenuItem;
-import android.widget.AbsListView;
-
-import java.util.LinkedList;
-import java.util.List;
 
 /**
  * 本应用所有{@link android.app.Activity Activity}的父类。
  */
 public abstract class BaseActivity extends AppCompatActivity {
 
-    // Durations for certain animations we use:
-    protected static final int HEADER_HIDE_ANIM_DURATION = 300;
-
-    /**
-     * THRESHOLD for calculate approximate currentY and deltaY of {@link #onMainContentScrolled}
-     */
-    final static int ITEMS_THRESHOLD = 0;
-
     private boolean mShowSettingsMenuItem = true;
 
     private Toolbar mActionBarToolbar;
 
-    // variables that control the Action Bar auto hide behavior (aka "quick recall")
-    private boolean mActionBarAutoHideEnabled = false;
-
-    private int mActionBarAutoHideSensivity = 0;
-
-    private int mActionBarAutoHideMinY = 0;
-
-    private int mActionBarAutoHideSignal = 0;
-
-    private boolean mActionBarShown = true;
-
-    private int mProgressBarTopWhenActionBarShown;
-
-    private int mProgressBarTopWhenActionBarHidden = 0;
-
-    private List mSwipeRefreshLayouts = new LinkedList<>();
-
-    private final AbsListView.OnScrollListener mOnScrollListenerForAbsListView =
-            new AbsListView.OnScrollListener() {
-                int lastFvi = 0;
-
-                @Override
-                public void onScrollStateChanged(AbsListView view, int scrollState) {
-                }
-
-                @Override
-                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
-                    onMainContentScrolled(firstVisibleItem <= ITEMS_THRESHOLD ? 0 : Integer.MAX_VALUE,
-                            lastFvi - firstVisibleItem > 0 ? Integer.MIN_VALUE :
-                                    lastFvi == firstVisibleItem ? 0 : Integer.MAX_VALUE
-                    );
-                    lastFvi = firstVisibleItem;
-                }
-            };
-
-    private final RecyclerView.OnScrollListener mOnScrollListenerForRecyclerView =
-            new RecyclerView.OnScrollListener() {
-                @Override
-                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
-                    super.onScrolled(recyclerView, dx, dy);
-                    int firstVisibleItem = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
-                    onMainContentScrolled(firstVisibleItem <= ITEMS_THRESHOLD ? 0 : Integer.MAX_VALUE, dy);
-                }
-            };
-
     @Override
     protected void onResume() {
         super.onResume();
@@ -117,12 +57,14 @@ public boolean onOptionsItemSelected(MenuItem item) {
         }
     }
 
+    // copy from https://github.com/google/iosched/blob/b3c3ae2a5b41e28c07383644d78e5c076288322f/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java
     @Override
     public void setContentView(int layoutResID) {
         super.setContentView(layoutResID);
         getActionBarToolbar();
     }
 
+    // copy from https://github.com/google/iosched/blob/b3c3ae2a5b41e28c07383644d78e5c076288322f/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java
     protected Toolbar getActionBarToolbar() {
         if (mActionBarToolbar == null) {
             mActionBarToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
@@ -133,112 +75,6 @@ protected Toolbar getActionBarToolbar() {
         return mActionBarToolbar;
     }
 
-    public void registerSwipeRefreshLayout(SwipeRefreshLayout swipeRefreshLayout) {
-        if (!mSwipeRefreshLayouts.contains(swipeRefreshLayout)) {
-            mSwipeRefreshLayouts.add(swipeRefreshLayout);
-            updateSwipeRefreshProgressBarTop();
-        }
-    }
-
-    public void deregisterSwipeRefreshLayout(SwipeRefreshLayout swipeRefreshLayout) {
-        if (mSwipeRefreshLayouts.contains(swipeRefreshLayout)) {
-            mSwipeRefreshLayouts.remove(swipeRefreshLayout);
-        }
-    }
-
-    protected void setProgressBarTop(
-            int progressBarTopWhenActionBarShown, int progressBarTopWhenActionBarHidden) {
-        mProgressBarTopWhenActionBarShown = progressBarTopWhenActionBarShown;
-        mProgressBarTopWhenActionBarHidden = progressBarTopWhenActionBarHidden;
-        updateSwipeRefreshProgressBarTop();
-    }
-
-    private void updateSwipeRefreshProgressBarTop() {
-        if (mSwipeRefreshLayouts.isEmpty()) {
-            return;
-        }
-
-        int progressBarStartMargin = getResources().getDimensionPixelSize(
-                R.dimen.swipe_refresh_progress_bar_start_margin);
-        int progressBarEndMargin = getResources().getDimensionPixelSize(
-                R.dimen.swipe_refresh_progress_bar_end_margin);
-        int top = mActionBarShown ?
-                mProgressBarTopWhenActionBarShown : mProgressBarTopWhenActionBarHidden;
-        for (SwipeRefreshLayout swipeRefreshLayout : mSwipeRefreshLayouts) {
-            swipeRefreshLayout.setProgressViewOffset(false,
-                    top + progressBarStartMargin, top + progressBarEndMargin);
-        }
-    }
-
-    /**
-     * Initializes the Action Bar auto-hide (aka Quick Recall) effect.
-     */
-    private void initActionBarAutoHide() {
-        if (!mActionBarAutoHideEnabled) {
-            mActionBarAutoHideEnabled = true;
-            mActionBarAutoHideMinY = getResources().getDimensionPixelSize(
-                    R.dimen.action_bar_auto_hide_min_y);
-            mActionBarAutoHideSensivity = getResources().getDimensionPixelSize(
-                    R.dimen.action_bar_auto_hide_sensivity);
-        }
-    }
-
-    /**
-     * 取得用于触发Action Bar auto hide的OnScrollListener
-     */
-    public AbsListView.OnScrollListener getOnScrollListenerForAbsListView() {
-        initActionBarAutoHide();
-        return mOnScrollListenerForAbsListView;
-    }
-
-    /**
-     * 取得用于触发Action Bar auto hide的OnScrollListener
-     */
-    public RecyclerView.OnScrollListener getOnScrollListenerForRecyclerView() {
-        initActionBarAutoHide();
-        return mOnScrollListenerForRecyclerView;
-    }
-
-    /**
-     * Indicates that the main content has scrolled (for the purposes of showing/hiding
-     * the action bar for the "action bar auto hide" effect). currentY and deltaY may be exact
-     * (if the underlying view supports it) or may be approximate indications:
-     * deltaY may be INT_MAX to mean "scrolled forward indeterminately" and INT_MIN to mean
-     * "scrolled backward indeterminately".  currentY may be 0 to mean "somewhere close to the
-     * start of the list" and INT_MAX to mean "we don't know, but not at the start of the list"
-     */
-    private void onMainContentScrolled(int currentY, int deltaY) {
-        if (deltaY > mActionBarAutoHideSensivity) {
-            deltaY = mActionBarAutoHideSensivity;
-        } else if (deltaY < -mActionBarAutoHideSensivity) {
-            deltaY = -mActionBarAutoHideSensivity;
-        }
-
-        if (Math.signum(deltaY) * Math.signum(mActionBarAutoHideSignal) < 0) {
-            // deltaY is a motion opposite to the accumulated signal, so reset signal
-            mActionBarAutoHideSignal = deltaY;
-        } else {
-            // add to accumulated signal
-            mActionBarAutoHideSignal += deltaY;
-        }
-
-        boolean shouldShow = currentY < mActionBarAutoHideMinY ||
-                mActionBarAutoHideSignal <= -mActionBarAutoHideSensivity;
-        autoShowOrHideActionBar(shouldShow);
-    }
-
-    protected void autoShowOrHideActionBar(boolean show) {
-        if (show == mActionBarShown) {
-            return;
-        }
-
-        mActionBarShown = show;
-        updateSwipeRefreshProgressBarTop();
-        onActionBarAutoShowOrHide(show);
-    }
-
-    protected void onActionBarAutoShowOrHide(boolean shown) {}
-
     /**
      * 有新添加的菜单项
      */
diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/MainActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/MainActivity.java
index 153a82e..9bc0b3c 100644
--- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/MainActivity.java
+++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/MainActivity.java
@@ -20,9 +20,7 @@
 import android.support.v4.app.FragmentPagerAdapter;
 import android.support.v4.view.ViewPager;
 import android.util.Log;
-import android.view.View;
 import android.view.ViewGroup;
-import android.view.animation.DecelerateInterpolator;
 
 import java.util.Arrays;
 import java.util.HashMap;
@@ -66,8 +64,6 @@ public class MainActivity extends LoginableBaseActivity {
 
     private ViewPager mPager;
 
-    private int mActionbarHeight;
-
     //--------------------------------------------------------------------------
     // 覆写Activity的生命周期方法
     //--------------------------------------------------------------------------
@@ -102,11 +98,6 @@ public void onPageSelected(int position) {
         });
         // goto default pager
         mPager.setCurrentItem(DEFAULT_POSITION);
-
-        mActionbarHeight = getResources().getDimensionPixelSize(R.dimen.action_bar_height);
-        int pageIndicatorHeight =
-                getResources().getDimensionPixelSize(R.dimen.page_indicator_height);
-        setProgressBarTop(mActionbarHeight + pageIndicatorHeight, pageIndicatorHeight);
     }
 
     @Override
@@ -133,24 +124,6 @@ public void onSaveInstanceState(@NonNull Bundle outState) {
         super.onSaveInstanceState(outState);
     }
 
-    @Override
-    protected void onActionBarAutoShowOrHide(boolean shown) {
-        View header = findViewById(R.id.header);
-        if (header != null) {
-            if (shown) {
-                header.animate()
-                        .translationY(0)
-                        .setDuration(HEADER_HIDE_ANIM_DURATION)
-                        .setInterpolator(new DecelerateInterpolator());
-            } else {
-                header.animate()
-                        .translationY(-mActionbarHeight)
-                        .setDuration(HEADER_HIDE_ANIM_DURATION)
-                        .setInterpolator(new DecelerateInterpolator());
-            }
-        }
-    }
-
     //--------------------------------------------------------------------------
     // 新声明方法
     //--------------------------------------------------------------------------
diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/HistoryFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/HistoryFragment.java
index 234005d..54af42d 100644
--- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/HistoryFragment.java
+++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/HistoryFragment.java
@@ -32,42 +32,33 @@
  */
 public class HistoryFragment extends Fragment {
 
-    private ArrayList favoriteBeans;
-    private FavoriteAdapter adapter;
-
-    private WindowManager windowManager = null;
-
     private View v;
     private ListView favoriteListView;
+    private ArrayList favoriteBeans;
+    private FavoriteAdapter adapter;
+    private VolleySingleton mVolleySingleton;
     private TextView mTvHint;
 
+    private WindowManager windowManager = null;
+    private WindowManager.LayoutParams windowParams = null;
     private View deleteView = null;
+
     private boolean mIsDelButtonCreate;
     private boolean mIsCreated;
 
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        favoriteBeans = new ArrayList<>(20);
-        adapter = new FavoriteAdapter(
-                getActivity(), favoriteBeans,
-                VolleySingleton.getInstance(getActivity()).getImageLoader());
-
-        windowManager = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
-    }
-
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
         v = inflater.inflate(R.layout.fragment_history, container, false);
         favoriteListView = (ListView) v.findViewById(R.id.favorite_list);
         mTvHint = (TextView) v.findViewById(R.id.favorite_hint);
+        favoriteBeans = DBManager.getInstance(getActivity()).getAllHistory();
         return v;
     }
 
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
+        mVolleySingleton = VolleySingleton.getInstance(getActivity());
 
         favoriteListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
@@ -83,7 +74,7 @@ public void onItemClick(AdapterView parent, View view, int position, long id)
             public boolean onItemLongClick(AdapterView parent, View view, final int position, long id) {
                 int[] locationInWindow = new int[2];
                 view.getLocationInWindow(locationInWindow);
-                WindowManager.LayoutParams windowParams = new WindowManager.LayoutParams();
+                windowParams = new WindowManager.LayoutParams();
                 windowParams.gravity = Gravity.TOP | Gravity.LEFT;
                 windowParams.x = locationInWindow[0] + view.getWidth() / 2;
                 windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
@@ -95,6 +86,7 @@ public boolean onItemLongClick(AdapterView parent, View view, final int posit
                         | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
                 windowParams.format = PixelFormat.TRANSLUCENT;
                 windowParams.windowAnimations = 0;
+                windowManager = (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
                 if (deleteView != null) {
                     windowManager.removeViewImmediate(deleteView);
                 }
@@ -142,6 +134,7 @@ public boolean onTouch(View v, MotionEvent event) {
             }
         });
 
+        adapter = new FavoriteAdapter(getActivity(), favoriteBeans, mVolleySingleton.getImageLoader());
         favoriteListView.setAdapter(adapter);
         favoriteListView.setVisibility(View.VISIBLE);
         mIsCreated = true;
@@ -165,9 +158,6 @@ public void onPause() {
     public void onDestroyView() {
         mTvHint = null;
         favoriteListView.setAdapter(null);
-        favoriteListView.setOnTouchListener(null);
-        favoriteListView.setOnItemLongClickListener(null);
-        favoriteListView.setOnItemClickListener(null);
         favoriteListView = null;
         v = null;
         super.onDestroyView();
diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/SwipeRefreshFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/SwipeRefreshFragment.java
index d7bb00b..1eda8a5 100644
--- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/SwipeRefreshFragment.java
+++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/SwipeRefreshFragment.java
@@ -1,7 +1,6 @@
 package com.optimalorange.cooltechnologies.ui.fragment;
 
 import com.optimalorange.cooltechnologies.R;
-import com.optimalorange.cooltechnologies.ui.BaseActivity;
 
 import android.os.Bundle;
 import android.support.annotation.Nullable;
@@ -48,9 +47,6 @@ public boolean canChildScrollUp() {
                 return SwipeRefreshFragment.this.canChildScrollUp();
             }
         };
-        if (getActivity() instanceof BaseActivity) {
-            ((BaseActivity) getActivity()).registerSwipeRefreshLayout(mSwipeRefreshLayout);
-        }
         mSwipeRefreshLayout.addView(
                 mChildView,
                 SwipeRefreshLayout.LayoutParams.MATCH_PARENT,
@@ -70,9 +66,6 @@ public void onDestroyView() {
         mSwipeRefreshLayout.clearAnimation(); // hide circle progress view
         mSwipeRefreshLayout.setOnRefreshListener(null);
         mSwipeRefreshLayout.removeView(mChildView);
-        if (getActivity() instanceof BaseActivity) {
-            ((BaseActivity) getActivity()).deregisterSwipeRefreshLayout(mSwipeRefreshLayout);
-        }
         mSwipeRefreshLayout = null;
         mChildView = null;
         super.onDestroyView();
diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/view/AutoHideActionBar.aj b/app/src/main/java/com/optimalorange/cooltechnologies/ui/view/AutoHideActionBar.aj
deleted file mode 100644
index f39425a..0000000
--- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/view/AutoHideActionBar.aj
+++ /dev/null
@@ -1,138 +0,0 @@
-package com.optimalorange.cooltechnologies.ui.view;
-
-import com.optimalorange.cooltechnologies.R;
-import com.optimalorange.cooltechnologies.ui.MainActivity;
-import com.optimalorange.cooltechnologies.ui.fragment.FavoriteFragment;
-import com.optimalorange.cooltechnologies.ui.fragment.HistoryFragment;
-import com.optimalorange.cooltechnologies.ui.fragment.ListGenresFragment;
-import com.optimalorange.cooltechnologies.ui.fragment.ListVideosFragment;
-import com.optimalorange.cooltechnologies.ui.fragment.PromotionFragment;
-
-import android.os.Bundle;
-import android.app.Activity;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.support.v7.widget.RecyclerView;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-
-public aspect AutoHideActionBar {
-
-    private static final String LOG_TAG = AutoHideActionBar.class.getSimpleName();
-
-    private interface SupportAutoHideActionBarEnable {}
-    declare parents: (PromotionFragment || ListVideosFragment || ListGenresFragment
-            || FavoriteFragment || HistoryFragment) implements SupportAutoHideActionBarEnable;
-
-    private MainActivity SupportAutoHideActionBarEnable.mMainActivity = null;
-    private int SupportAutoHideActionBarEnable.mActionBarHeight = -1;
-    private int SupportAutoHideActionBarEnable.mPageIndicatorHeight = -1;
-    private ViewGroup SupportAutoHideActionBarEnable.mScrollableView = null;
-
-    private pointcut inFragmentPackage(): within(com.optimalorange.cooltechnologies.ui.fragment.*);
-
-    after(SupportAutoHideActionBarEnable fragment): inFragmentPackage() && this(fragment)
-            && execution(void onCreate(Bundle)) {
-        final Activity activity = ((Fragment) fragment).getActivity();
-        if (activity instanceof MainActivity) {
-            fragment.mMainActivity = (MainActivity) activity;
-            fragment.mActionBarHeight =
-                    activity.getResources().getDimensionPixelSize(R.dimen.action_bar_height);
-            fragment.mPageIndicatorHeight =
-                    activity.getResources().getDimensionPixelSize(R.dimen.page_indicator_height);
-        } else {
-            fragment.mMainActivity = null;
-        }
-    }
-
-    after(SupportAutoHideActionBarEnable fragment) returning(View view): inFragmentPackage() &&
-            this(fragment) && execution(View onCreate*View(LayoutInflater, ViewGroup, Bundle)) {
-        if (fragment.mMainActivity == null) {
-            return;
-        }
-        fragment.mScrollableView = findScrollableView(fragment, view);
-
-        final int paddingTop = fragment.mActionBarHeight + fragment.mPageIndicatorHeight;
-        for (View container : findOtherContainers(fragment, view)) {
-            setPaddingTop(container, paddingTop);
-        }
-        if (fragment.mScrollableView != null) {
-            fragment.mScrollableView.setClipToPadding(false);
-            setPaddingTop(fragment.mScrollableView, paddingTop);
-            setOnScrollListener(fragment.mScrollableView, fragment.mMainActivity);
-        }
-
-    }
-
-    before(SupportAutoHideActionBarEnable fragment):
-            inFragmentPackage() && this(fragment) && execution(void onDestroyView()) {
-        if (fragment.mScrollableView != null) {
-            clearOnScrollListener(fragment.mScrollableView);
-            fragment.mScrollableView = null;
-        }
-    }
-
-    private static void setPaddingTop(View v, int paddingTop) {
-        v.setPadding(v.getPaddingLeft(), paddingTop, v.getPaddingRight(), v.getPaddingBottom());
-    }
-
-    @Nullable
-    private static ViewGroup findScrollableView(Object fragment, View rootView) {
-        int scrollableViewId;
-        if (fragment instanceof PromotionFragment) {
-            return null;
-        } else if (fragment instanceof ListVideosFragment) {
-            scrollableViewId = R.id.grid_view;
-        } else if (fragment instanceof ListGenresFragment) {
-            scrollableViewId = R.id.recycler_view;
-        } else if (fragment instanceof FavoriteFragment || fragment instanceof HistoryFragment) {
-            scrollableViewId = R.id.favorite_list;
-        } else {
-            throw new IllegalArgumentException("unknown fragment:" + fragment);
-        }
-        return (ViewGroup) rootView.findViewById(scrollableViewId);
-    }
-
-    @NonNull
-    private static View[] findOtherContainers(Object fragment, View rootView) {
-        if (fragment instanceof PromotionFragment) {
-            return new View[]{rootView.findViewById(R.id.main_content)};
-        } else if (fragment instanceof ListVideosFragment
-                || fragment instanceof ListGenresFragment) {
-            return new View[]{
-                    rootView.findViewById(android.R.id.empty),
-                    rootView.findViewById(R.id.no_connection)};
-        } else if (fragment instanceof FavoriteFragment || fragment instanceof HistoryFragment) {
-            return new View[]{rootView.findViewById(R.id.favorite_hint)};
-        } else {
-            throw new IllegalArgumentException("unknown fragment:" + fragment);
-        }
-    }
-
-    private static void setOnScrollListener(View scrollableView, MainActivity mainActivity) {
-        if (scrollableView instanceof RecyclerView) {
-            ((RecyclerView) scrollableView)
-                    .setOnScrollListener(mainActivity.getOnScrollListenerForRecyclerView());
-        } else if (scrollableView instanceof AbsListView) {
-            ((AbsListView) scrollableView)
-                    .setOnScrollListener(mainActivity.getOnScrollListenerForAbsListView());
-        } else {
-            Log.w(LOG_TAG, "Can't set ScrollListener to scrollableView:" + scrollableView);
-        }
-    }
-
-    private static void clearOnScrollListener(View scrollableView) {
-        if (scrollableView instanceof RecyclerView) {
-            ((RecyclerView) scrollableView).setOnScrollListener(null);
-        } else if (scrollableView instanceof AbsListView) {
-            ((AbsListView) scrollableView).setOnScrollListener(null);
-        } else {
-            Log.w(LOG_TAG, "Can't clear ScrollListener of scrollableView:" + scrollableView);
-        }
-    }
-
-}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 0a773b7..edb49ab 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,34 +1,28 @@
 
-
 
-    
+    
 
-    
-
-        
-
-        
+            android:layout_weight="0"
+            />
 
-    
+    
 
-
+
diff --git a/app/src/main/res/layout/fragment_promotion.xml b/app/src/main/res/layout/fragment_promotion.xml
index 6445a00..3eaf819 100644
--- a/app/src/main/res/layout/fragment_promotion.xml
+++ b/app/src/main/res/layout/fragment_promotion.xml
@@ -1,7 +1,6 @@
 
 
-
-
-    48dp
-
-
diff --git a/app/src/main/res/values-sw600dp/dimens.xml b/app/src/main/res/values-sw600dp/dimens.xml
deleted file mode 100644
index cac94b5..0000000
--- a/app/src/main/res/values-sw600dp/dimens.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-    64dp
-
-
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 1292a8e..998c95a 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -2,23 +2,7 @@
     
     16dp
     16dp
-
-    56dp
-
-    
-    152dp
-    48dp
-
-    -40dp
-    16dp
-
-    30dp
-    4dp
-    4dp
-    0dp
-    5dp
-
-    
+    
     0dp
     0dp
     120dp
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index ca77cec..4d237d0 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -12,7 +12,6 @@
         @color/accent
         
-        @dimen/action_bar_height
         @style/CustomTitlePageIndicator
     
 
@@ -33,11 +32,11 @@
     
     
 
     
@@ -29,18 +28,4 @@
 
     
-
 

From 08b7b2d43db4c028eb64239fcc101fb8c601420f Mon Sep 17 00:00:00 2001
From: Bai Jie 
Date: Fri, 5 Jun 2015 20:17:16 +0800
Subject: [PATCH 028/120] =?UTF-8?q?=E4=B8=BAMainActivity=E6=B7=BB=E5=8A=A0?=
 =?UTF-8?q?AppBarLayout=E5=92=8CTabLayout?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/build.gradle                              |  1 +
 .../cooltechnologies/ui/MainActivity.java     |  4 +++
 app/src/main/res/layout/activity_main.xml     | 32 +++++++++++++++----
 app/src/main/res/layout/toolbar_actionbar.xml |  7 ++--
 4 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/app/build.gradle b/app/build.gradle
index bc5dabd..670de4c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -73,6 +73,7 @@ dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     compile 'com.android.support:support-v4:22.2.0'
     compile 'com.android.support:appcompat-v7:22.2.0'
+    compile 'com.android.support:design:22.2.0'
     compile 'com.android.support:cardview-v7:22.2.0'
     compile 'com.android.support:recyclerview-v7:22.2.0'
     compile 'com.android.support:support-v13:22.2.0'
diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/MainActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/MainActivity.java
index 4f81a28..1b26eeb 100644
--- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/MainActivity.java
+++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/MainActivity.java
@@ -14,6 +14,7 @@
 import android.os.Bundle;
 import android.preference.PreferenceManager;
 import android.support.annotation.NonNull;
+import android.support.design.widget.TabLayout;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentPagerAdapter;
@@ -81,6 +82,9 @@ protected void onCreate(Bundle savedInstanceState) {
         );
         mPager = (ViewPager) findViewById(R.id.pager);
         mPager.setAdapter(mAdapter);
+        // Bind the tabs to the ViewPager
+        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
+        tabLayout.setupWithViewPager(mPager);
         // goto default pager
         mPager.setCurrentItem(DEFAULT_POSITION);
     }
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index d754e32..de4a207 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,21 +1,39 @@
 
-
 
-    
+    
+
+        
+
+        
+
+    
 
     
 
-
+
diff --git a/app/src/main/res/layout/toolbar_actionbar.xml b/app/src/main/res/layout/toolbar_actionbar.xml
index 6d91edc..93c3fcf 100644
--- a/app/src/main/res/layout/toolbar_actionbar.xml
+++ b/app/src/main/res/layout/toolbar_actionbar.xml
@@ -1,11 +1,12 @@
+
 

From 244d2ebbb4b330392dc2a7ee2e8bccd522b3121f Mon Sep 17 00:00:00 2001
From: Bai Jie 
Date: Sat, 24 Oct 2015 23:00:35 +0800
Subject: [PATCH 029/120] update gradle version to 2.8

---
 gradle/wrapper/gradle-wrapper.jar        | Bin 49896 -> 53637 bytes
 gradle/wrapper/gradle-wrapper.properties |   4 ++--
 gradlew                                  |  10 +++-------
 3 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 8c0fb64a8698b08ecc4158d828ca593c4928e9dd..05ef575b0cd0173fc735f2857ce4bd594ce4f6bd 100644
GIT binary patch
delta 46945
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
gX$Y4zSjU*K+Y9REGVcCoqtRGf9?!GhyVZp

delta 43373
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�{>`y
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

diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index e546be0..1cc719d 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Jun 03 11:36:17 CST 2015
+#Sat Oct 24 22:58:48 CST 2015
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-bin.zip
diff --git a/gradlew b/gradlew
index 91a7e26..9d82f78 100755
--- a/gradlew
+++ b/gradlew
@@ -42,11 +42,6 @@ case "`uname`" in
     ;;
 esac
 
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
-    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
 # Attempt to set APP_HOME
 # Resolve links: $0 may be a link
 PRG="$0"
@@ -61,9 +56,9 @@ while [ -h "$PRG" ] ; do
     fi
 done
 SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
+cd "`dirname \"$PRG\"`/" >/dev/null
 APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
+cd "$SAVED" >/dev/null
 
 CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
 
@@ -114,6 +109,7 @@ fi
 if $cygwin ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
 
     # We build the pattern for arguments to be converted via cygpath
     ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`

From c0bc0a83760807c8b7051cac50229397a1b09b3e Mon Sep 17 00:00:00 2001
From: Bai Jie 
Date: Sun, 25 Oct 2015 18:34:59 +0800
Subject: [PATCH 030/120] =?UTF-8?q?=E6=8A=8Abuildscript=E9=85=8D=E7=BD=AE?=
 =?UTF-8?q?=E7=A7=BB=E5=88=B0=E4=BD=BF=E7=94=A8=E5=AE=83=E7=9A=84=E5=9C=B0?=
 =?UTF-8?q?=E6=96=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/build.gradle | 15 +++++++++++++++
 build.gradle     | 15 ---------------
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/app/build.gradle b/app/build.gradle
index 670de4c..78e34d8 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,3 +1,18 @@
+buildscript {
+    repositories {
+        mavenCentral()
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:1.2.3'
+        classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0'
+        classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.12'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
 apply plugin: 'android-sdk-manager'
 apply plugin: 'com.android.application'
 apply plugin: 'android-aspectj'
diff --git a/build.gradle b/build.gradle
index d7819ce..91e52a4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,20 +1,5 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
 
-buildscript {
-    repositories {
-        mavenCentral()
-        jcenter()
-    }
-    dependencies {
-        classpath 'com.android.tools.build:gradle:1.2.3'
-        classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0'
-        classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.12'
-
-        // NOTE: Do not place your application dependencies here; they belong
-        // in the individual module build.gradle files
-    }
-}
-
 allprojects {
     group = PROJECTS_GROUP
     version = new Version(VERSION_NAME)

From 4f4154b1454a3309f63bc5cf6c18d7234a87aacc Mon Sep 17 00:00:00 2001
From: Bai Jie 
Date: Sun, 25 Oct 2015 20:01:55 +0800
Subject: [PATCH 031/120] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BD=BF=E7=94=A8?=
 =?UTF-8?q?=E7=9A=84Gradle=E6=8F=92=E4=BB=B6=E3=80=81build=E5=B7=A5?=
 =?UTF-8?q?=E5=85=B7=E3=80=81compileSdk=E3=80=81=E6=94=AF=E6=8C=81?=
 =?UTF-8?q?=E5=8C=85=E5=92=8C=E7=AC=AC=E4=B8=89=E6=96=B9=E5=BA=93=E7=89=88?=
 =?UTF-8?q?=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

resolved #22 更新使用的第三方库
---
 app/build.gradle | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/app/build.gradle b/app/build.gradle
index 78e34d8..db7e6fb 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -4,9 +4,9 @@ buildscript {
         jcenter()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:1.2.3'
+        classpath 'com.android.tools.build:gradle:1.4.0-beta6'
         classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0'
-        classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.12'
+        classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.13'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
@@ -15,11 +15,13 @@ buildscript {
 
 apply plugin: 'android-sdk-manager'
 apply plugin: 'com.android.application'
-apply plugin: 'android-aspectj'
+apply plugin: 'com.uphyca.android-aspectj'
 
 android {
-    compileSdkVersion 22
-    buildToolsVersion "22.0.1"
+    compileSdkVersion 23
+    buildToolsVersion "23.0.1"
+
+    useLibrary 'org.apache.http.legacy' //TODO remove this
 
     defaultConfig {
         applicationId "com.optimalorange.cooltechnologies"
@@ -86,13 +88,13 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
-    compile 'com.android.support:support-v4:22.2.0'
-    compile 'com.android.support:appcompat-v7:22.2.0'
-    compile 'com.android.support:design:22.2.0'
-    compile 'com.android.support:cardview-v7:22.2.0'
-    compile 'com.android.support:recyclerview-v7:22.2.0'
-    compile 'com.android.support:support-v13:22.2.0'
-    compile 'com.mcxiaoke.volley:library:1.0.16@aar'
+    compile 'com.android.support:support-v4:23.1.0'
+    compile 'com.android.support:appcompat-v7:23.1.0'
+    compile 'com.android.support:design:23.1.0'
+    compile 'com.android.support:cardview-v7:23.1.0'
+    compile 'com.android.support:recyclerview-v7:23.1.0'
+    compile 'com.android.support:support-v13:23.1.0'
+    compile 'com.mcxiaoke.volley:library:1.0.19@aar'
     compile 'com.etsy.android.grid:library:1.0.5'
     compile 'cpr.name.videoenabledwebview:library:1.0'
     compile 'com.umeng.update:library:2.5.0'

From d228e8c99379828f9c71b327ad35b3bbf37c4f03 Mon Sep 17 00:00:00 2001
From: Bai Jie 
Date: Sun, 25 Oct 2015 20:42:33 +0800
Subject: [PATCH 032/120] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20Travis=20CI=20?=
 =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .travis.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index f5a6e63..70638c6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,10 +9,10 @@ android:
     # - tools
 
     # The BuildTools version used by your project
-    - build-tools-22.0.1
+    - build-tools-23.0.1
 
     # The SDK version used to compile your project
-    - android-22
+    - android-23
 
     # Additional components
     #- extra-google-google_play_services

From 31ca24dd5e9d66713c1c06e4cdf658d56ee0eb06 Mon Sep 17 00:00:00 2001
From: Bai Jie 
Date: Sun, 25 Oct 2015 21:41:11 +0800
Subject: [PATCH 033/120] =?UTF-8?q?=E9=99=8D=E7=BA=A7android-aspectj?=
 =?UTF-8?q?=E6=8F=92=E4=BB=B6=EF=BC=8C=E6=96=B0=E7=89=88=E5=B0=9A=E4=B8=8D?=
 =?UTF-8?q?=E5=AE=8C=E5=96=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/build.gradle | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/build.gradle b/app/build.gradle
index db7e6fb..21f20f1 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -6,7 +6,7 @@ buildscript {
     dependencies {
         classpath 'com.android.tools.build:gradle:1.4.0-beta6'
         classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0'
-        classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.13'
+        classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.12'    //0.9.13尚不完善,暂不更新
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
@@ -15,7 +15,7 @@ buildscript {
 
 apply plugin: 'android-sdk-manager'
 apply plugin: 'com.android.application'
-apply plugin: 'com.uphyca.android-aspectj'
+apply plugin: 'android-aspectj'
 
 android {
     compileSdkVersion 23

From 26efd82add976cfb80ba0eff7c43af37ae0ef531 Mon Sep 17 00:00:00 2001
From: Bai Jie 
Date: Mon, 26 Oct 2015 00:29:48 +0800
Subject: [PATCH 034/120] =?UTF-8?q?=E8=AE=A9=20Travis=20CI=20=E4=BD=BF?=
 =?UTF-8?q?=E7=94=A8=E6=96=B0=E7=89=88=20SDK=20platform-tools?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .travis.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index 70638c6..8975d86 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,7 @@ android:
   components:
     # Uncomment the lines below if you want to
     # use the latest revision of Android SDK Tools
-    # - platform-tools
+    - platform-tools
     # - tools
 
     # The BuildTools version used by your project

From 61eb855504cac48d0c9f9e186ed6a149ef0674a8 Mon Sep 17 00:00:00 2001
From: Bai Jie 
Date: Tue, 27 Oct 2015 22:57:57 +0800
Subject: [PATCH 035/120] =?UTF-8?q?=E6=9B=B4=E6=96=B0Travis=20CI=E5=9B=BE?=
 =?UTF-8?q?=E6=A0=87=E9=93=BE=E6=8E=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index ce09d74..c50fa55 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 炫科技
 ================
 
-[![Build Status](https://travis-ci.org/OptimalOrange/CoolTechnologies.svg?branch=dev)](https://travis-ci.org/OptimalOrange/CoolTechnologies)
+[![Build Status](https://travis-ci.org/OptimalOrange/CoolTechnologies.svg?branch=master)](https://travis-ci.org/OptimalOrange/CoolTechnologies)
 
 功能
 -------------

From a878a690cc5572235601d973059a5549c7454071 Mon Sep 17 00:00:00 2001
From: Bai Jie 
Date: Wed, 28 Oct 2015 20:47:39 +0800
Subject: [PATCH 036/120] =?UTF-8?q?=E4=BD=BF=E7=94=A8DestroyFavoriteReques?=
 =?UTF-8?q?t=E5=92=8CVolley=E5=AE=9E=E7=8E=B0=E2=80=9C=E6=94=B6=E8=97=8F?=
 =?UTF-8?q?=E2=80=9D=E9=A1=B5=E9=9D=A2=E7=9A=84=E5=8F=96=E6=B6=88=E6=94=B6?=
 =?UTF-8?q?=E8=97=8F=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

resolved #30 去除对Apache HTTP Client的依赖
---
 app/build.gradle                              |   2 -
 .../ui/fragment/FavoriteFragment.java         | 154 ++++++++----------
 2 files changed, 64 insertions(+), 92 deletions(-)

diff --git a/app/build.gradle b/app/build.gradle
index 21f20f1..45ae57e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -21,8 +21,6 @@ android {
     compileSdkVersion 23
     buildToolsVersion "23.0.1"
 
-    useLibrary 'org.apache.http.legacy' //TODO remove this
-
     defaultConfig {
         applicationId "com.optimalorange.cooltechnologies"
         minSdkVersion 15
diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/FavoriteFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/FavoriteFragment.java
index e2a8507..ad8bc1d 100644
--- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/FavoriteFragment.java
+++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/FavoriteFragment.java
@@ -9,6 +9,7 @@
 import com.optimalorange.cooltechnologies.R;
 import com.optimalorange.cooltechnologies.adapter.FavoriteAdapter;
 import com.optimalorange.cooltechnologies.entity.FavoriteBean;
+import com.optimalorange.cooltechnologies.network.DestroyFavoriteRequest;
 import com.optimalorange.cooltechnologies.network.NetworkChecker;
 import com.optimalorange.cooltechnologies.network.VolleySingleton;
 import com.optimalorange.cooltechnologies.storage.DefaultSharedPreferencesSingleton;
@@ -16,15 +17,6 @@
 import com.optimalorange.cooltechnologies.ui.PlayVideoActivity;
 import com.umeng.analytics.MobclickAgent;
 
-import org.apache.http.HttpResponse;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.message.BasicNameValuePair;
-import org.apache.http.protocol.HTTP;
-import org.apache.http.util.EntityUtils;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -33,9 +25,6 @@
 import android.content.Intent;
 import android.graphics.PixelFormat;
 import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -47,8 +36,6 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
@@ -60,6 +47,8 @@ public class FavoriteFragment extends SwipeRefreshFragment {
 
     private static final String DEFAULT_CATEGORY_LABEL= "科技";
 
+    private String mYoukuClientId;
+
     private View v;
     private static final String FAVORITE_BASE_URL = "https://openapi.youku.com/v2/videos/favorite/by_me.json";
     private ListView favoriteListView;
@@ -75,18 +64,12 @@ public class FavoriteFragment extends SwipeRefreshFragment {
     private ArrayList favoriteBeans;
     private FavoriteAdapter adapter;
 
-    private static final String BASE_FAVORITE_DELETE_URL = "https://openapi.youku.com/v2/videos/favorite/destroy.json";
-    private static final int DELETE_FAVORITE_OK = 0;
-    private static final int DELETE_FAVORITE_ERROR = 1;
     private int page = 1;
     private int total = 0;
     private int currentCount = 0;
     private TextView tvViewMore;
     private View footer;
 
-    private Handler mUiThreadHandler =
-            new Handler(Looper.getMainLooper(), new HandlerCallback(new WeakReference<>(this)));
-
     private final LoginableBaseActivity.OnLoginStatusChangeListener mOnLoginStatusChangeListener =
             new LoginableBaseActivity.OnLoginStatusChangeListener() {
                 @Override
@@ -102,6 +85,14 @@ public void onLoginStatusChanged(boolean hasLoggedIn) {
 
     private boolean mIsDelButtonCreate;
 
+    @Override
+    public void onAttach(Context context) {
+        super.onAttach(context);
+
+        mVolleySingleton = VolleySingleton.getInstance(getActivity());
+        mYoukuClientId = getString(R.string.youku_client_id);
+    }
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -126,7 +117,6 @@ public void onRefresh() {
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
-        mVolleySingleton = VolleySingleton.getInstance(getActivity());
         mDefaultSharedPreferencesSingleton =
                 DefaultSharedPreferencesSingleton.getInstance(getActivity());
         ((LoginableBaseActivity) getActivity())
@@ -376,86 +366,70 @@ private void sendDeleteRequest(String id, final int index) {
             Toast.makeText(getActivity(), R.string.favorite_delete_no_login, Toast.LENGTH_SHORT).show();
             return;
         }
-        final HttpPost request = new HttpPost(BASE_FAVORITE_DELETE_URL);
-        ArrayList paramList = new ArrayList();
-        BasicNameValuePair param;
-        param = new BasicNameValuePair("client_id", getString(R.string.youku_client_id));
-        paramList.add(param);
-        param = new BasicNameValuePair("access_token", token);
-        paramList.add(param);
-        param = new BasicNameValuePair("video_id", id);
-        paramList.add(param);
-        try {
-            request.setEntity(new UrlEncodedFormEntity(paramList, HTTP.UTF_8));
-        } catch (UnsupportedEncodingException e) {
-            e.printStackTrace();
-        }
 
-        new Thread(new Runnable() {
-            @Override
-            public void run() {
-                HttpClient client = new DefaultHttpClient();
-                try {
-                    HttpResponse response = client.execute(request);
-                    Message msg = new Message();
-                    if (response.getStatusLine().getStatusCode() == 200) {
-                        msg.what = DELETE_FAVORITE_OK;
-                        msg.arg1 = index;
-                        msg.obj = EntityUtils.toString(response.getEntity());
-                        mUiThreadHandler.sendMessage(msg);
-                    } else {
-                        msg.what = DELETE_FAVORITE_ERROR;
-                        mUiThreadHandler.sendMessage(msg);
-                    }
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-        }).start();
+        mVolleySingleton.addToRequestQueue(buildDestroyFavoriteRequest(token, id, index));
     }
 
-    /**
-     * Note必须在UI线程中调用此{@link HandlerCallback}。
-     */
-    private static class HandlerCallback implements Handler.Callback {
+    /** 创建取消收藏的请求 */
+    private DestroyFavoriteRequest buildDestroyFavoriteRequest(
+            String token, String videoId, int videoIndexInListView) {
+        final DestroyFavoriteRequestHandler handler = new DestroyFavoriteRequestHandler(
+                videoIndexInListView, new WeakReference<>(getContext()), new WeakReference<>(this));
+        return new DestroyFavoriteRequest.Builder()
+                .setClient_id(mYoukuClientId)
+                .setVideo_id(videoId)
+                .setAccess_token(token)
+                .setResponseListener(handler)
+                .setErrorListener(handler)
+                .build();
+    }
+
+    private static class DestroyFavoriteRequestHandler
+            implements Response.Listener, Response.ErrorListener {
+
+        private final int mVideoIndexInListView;
+
+        private final WeakReference mContextWeakReference;
 
-        private final WeakReference mOuterClass;
+        private final WeakReference mOwner;
 
-        private HandlerCallback(WeakReference outerClass) {
-            mOuterClass = outerClass;
+        private DestroyFavoriteRequestHandler(
+                int videoIndexInListView,
+                WeakReference contextWeakReference,
+                WeakReference owner) {
+            mVideoIndexInListView = videoIndexInListView;
+            mContextWeakReference = contextWeakReference;
+            mOwner = owner;
         }
 
         @Override
-        public boolean handleMessage(Message msg) {
-            FavoriteFragment outerClass = mOuterClass.get();
-            if (outerClass == null) {
-                return msg.what == DELETE_FAVORITE_OK || msg.what == DELETE_FAVORITE_ERROR;
+        public void onErrorResponse(VolleyError error) {
+            final Context context = mContextWeakReference.get();
+            if (context != null) {
+                final String message = context.getString(R.string.favorite_delete_fail);
+                Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
             }
-            switch (msg.what) {
-                case DELETE_FAVORITE_OK:
-                    outerClass.favoriteBeans.remove(msg.arg1);
-                    outerClass.adapter.notifyDataSetChanged();
-                    outerClass.removeWindowView();
-                    Toast.makeText(
-                            outerClass.getActivity(),
-                            outerClass.getString(R.string.favorite_delete_success),
-                            Toast.LENGTH_SHORT)
-                            .show();
-                    if (outerClass.favoriteBeans.size() == 0) {
-                        outerClass.setHint(R.string.favorite_no_fav);
-                    }
-                    return true;
-                case DELETE_FAVORITE_ERROR:
-                    Toast.makeText(
-                            outerClass.getActivity(),
-                            outerClass.getString(R.string.favorite_delete_fail),
-                            Toast.LENGTH_SHORT)
-                            .show();
-                    return true;
-                default:
-                    return false;
+        }
+
+        @Override
+        public void onResponse(JSONObject response) {
+            final Context context = mContextWeakReference.get();
+            final FavoriteFragment owner = mOwner.get();
+            if (owner != null) {
+                //TODO add remove video method?
+                owner.favoriteBeans.remove(mVideoIndexInListView);
+                owner.adapter.notifyDataSetChanged();
+                owner.removeWindowView();
+                if (owner.favoriteBeans.size() == 0) {
+                    owner.setHint(R.string.favorite_no_fav);
+                }
+            }
+            if (context != null) {
+                final String message = context.getString(R.string.favorite_delete_success);
+                Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
             }
         }
+
     }
 
 }

From c6f5774dee6bdb2bb2d4b70438275aa61cb1543f Mon Sep 17 00:00:00 2001
From: Bai Jie 
Date: Wed, 28 Oct 2015 22:33:19 +0800
Subject: [PATCH 037/120] =?UTF-8?q?=E5=9C=A8SimpleRequest.onFinish?=
 =?UTF-8?q?=E9=87=8A=E6=94=BE=E8=B5=84=E6=BA=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../cooltechnologies/network/SimpleRequest.java           | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/network/SimpleRequest.java b/app/src/main/java/com/optimalorange/cooltechnologies/network/SimpleRequest.java
index f5a05cf..d146e42 100644
--- a/app/src/main/java/com/optimalorange/cooltechnologies/network/SimpleRequest.java
+++ b/app/src/main/java/com/optimalorange/cooltechnologies/network/SimpleRequest.java
@@ -10,7 +10,7 @@
  */
 public abstract class SimpleRequest extends Request {
 
-    private final Response.Listener mListener;
+    private Response.Listener mListener;
 
     public SimpleRequest(int method, String url, Response.Listener listener,
             Response.ErrorListener errorListener) {
@@ -18,6 +18,12 @@ public SimpleRequest(int method, String url, Response.Listener listener,
         mListener = listener;
     }
 
+    @Override
+    protected void onFinish() {
+        super.onFinish();
+        mListener = null;
+    }
+
     @Override
     protected void deliverResponse(T response) {
         mListener.onResponse(response);

From 6452115b2e432c98334e32e2dd7de2abeffe5aae Mon Sep 17 00:00:00 2001
From: Bai Jie 
Date: Thu, 29 Oct 2015 17:49:55 +0800
Subject: [PATCH 038/120] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E2=80=9C=E6=88=91?=
 =?UTF-8?q?=E6=94=B6=E8=97=8F=E7=9A=84=E8=A7=86=E9=A2=91=E2=80=9DGetMyFavo?=
 =?UTF-8?q?riteRequest?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../network/GetMyFavoriteRequest.java         | 188 ++++++++++++++++++
 1 file changed, 188 insertions(+)
 create mode 100644 app/src/main/java/com/optimalorange/cooltechnologies/network/GetMyFavoriteRequest.java

diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/network/GetMyFavoriteRequest.java b/app/src/main/java/com/optimalorange/cooltechnologies/network/GetMyFavoriteRequest.java
new file mode 100644
index 0000000..99491b2
--- /dev/null
+++ b/app/src/main/java/com/optimalorange/cooltechnologies/network/GetMyFavoriteRequest.java
@@ -0,0 +1,188 @@
+package com.optimalorange.cooltechnologies.network;
+
+import com.android.volley.Request;
+import com.android.volley.Response;
+import com.android.volley.toolbox.JsonObjectRequest;
+
+import org.json.JSONObject;
+
+import android.net.Uri;
+
+/**
+ * see http://open.youku.com/docs?id=53
+ */
+public class GetMyFavoriteRequest extends JsonObjectRequest {
+
+
+    public GetMyFavoriteRequest(
+            String url,
+            Response.Listener listener,
+            Response.ErrorListener errorListener) {
+        super(url, listener, errorListener);
+    }
+
+    public GetMyFavoriteRequest(
+            int method,
+            String url,
+            Response.Listener listener,
+            Response.ErrorListener errorListener) {
+        super(method, url, listener, errorListener);
+    }
+
+    public GetMyFavoriteRequest(
+            int method,
+            String url,
+            JSONObject jsonRequest,
+            Response.Listener listener,
+            Response.ErrorListener errorListener) {
+        super(method, url, jsonRequest, listener, errorListener);
+    }
+
+    public GetMyFavoriteRequest(
+            int method,
+            String url,
+            String requestBody,
+            Response.Listener listener,
+            Response.ErrorListener errorListener) {
+        super(method, url, requestBody, listener, errorListener);
+    }
+
+    public GetMyFavoriteRequest(
+            String url,
+            JSONObject jsonRequest,
+            Response.Listener listener,
+            Response.ErrorListener errorListener) {
+        super(url, jsonRequest, listener, errorListener);
+    }
+
+
+    public static class Builder {
+
+        private static final int YOUKU_API_REQUEST_METHOD = Request.Method.GET;
+
+        private static final String YOUKU_API_FAVORITE_ME =
+                "https://openapi.youku.com/v2/videos/favorite/by_me.json";
+
+        /**
+         * Listener to receive the comments response
+         */
+        private Response.Listener mResponseListener;
+
+        /**
+         * Error listener, or null to ignore errors.
+         */
+        private Response.ErrorListener mErrorListener;
+
+        private String client_id;
+
+        private String access_token;
+
+        private String orderby;
+
+        private Integer page;
+
+        private Integer count;
+
+        public Builder setResponseListener(
+                Response.Listener responseListener) {
+            mResponseListener = responseListener;
+            return this;
+        }
+
+        public Builder setErrorListener(Response.ErrorListener errorListener) {
+            mErrorListener = errorListener;
+            return this;
+        }
+
+        /**
+         * 应用Key
+ * 类型:String
+ * 必选 + */ + public Builder setClient_id(String client_id) { + this.client_id = client_id; + return this; + } + + /** + * OAuth2授权
+ * 类型:String
+ * 必选 + */ + public Builder setAccess_token(String access_token) { + this.access_token = access_token; + return this; + } + + /** + * 排序 favorite-time: 收藏时间
+ * 类型:String
+ * 可选
+ * 默认值:favorite-time
+ * 示例:favorite-time + */ + public Builder setOrderby(String orderby) { + this.orderby = orderby; + return this; + } + + /** + * 页数
+ * 类型:int
+ * 可选
+ * 默认值:1
+ * 示例:1 + */ + public Builder setPage(Integer page) { + this.page = page; + return this; + } + + /** + * 页大小
+ * 类型:int
+ * 可选
+ * 默认值:20
+ * 示例:20 + */ + public Builder setCount(Integer count) { + this.count = count; + return this; + } + + public GetMyFavoriteRequest build() { + return new GetMyFavoriteRequest( + YOUKU_API_REQUEST_METHOD, + buildUrl(), + mResponseListener, + mErrorListener + ); + } + + private String buildUrl() { + final Uri.Builder urlBuilder = Uri.parse(YOUKU_API_FAVORITE_ME).buildUpon(); + //必选参数 + if (client_id == null) { + throw new IllegalStateException("Please set client_id before build"); + } + if (access_token == null) { + throw new IllegalStateException("Please set video_id before build"); + } + urlBuilder.appendQueryParameter("client_id", client_id); + urlBuilder.appendQueryParameter("access_token", access_token); + //可选参数 + if (orderby != null) { + urlBuilder.appendQueryParameter("orderby", orderby); + } + if (page != null) { + urlBuilder.appendQueryParameter("page", page.toString()); + } + if (count != null) { + urlBuilder.appendQueryParameter("count", count.toString()); + } + return urlBuilder.build().toString(); + } + + } + +} From cdd9d7a73bd4fc1b4079895dd377cfecd56b414d Mon Sep 17 00:00:00 2001 From: Bai Jie Date: Thu, 29 Oct 2015 20:53:14 +0800 Subject: [PATCH 039/120] =?UTF-8?q?=E4=BD=BF=E7=94=A8DestroyFavoriteReques?= =?UTF-8?q?t=E5=92=8CVolleySingleton=E5=AE=9E=E7=8E=B0=E2=80=9C=E6=94=B6?= =?UTF-8?q?=E8=97=8F=E2=80=9D=E9=A1=B5=E9=9D=A2=E7=9A=84=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=94=B6=E8=97=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改 使用DestroyFavoriteRequest和VolleySingleton实现FavoriteFragment.getJsonData()方法 注:此commit尽量等价变换,仅有些细节改进 --- .../ui/fragment/FavoriteFragment.java | 170 ++++++++++++------ 1 file changed, 117 insertions(+), 53 deletions(-) diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/FavoriteFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/FavoriteFragment.java index ad8bc1d..3d82636 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/FavoriteFragment.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/FavoriteFragment.java @@ -1,15 +1,13 @@ package com.optimalorange.cooltechnologies.ui.fragment; -import com.android.volley.Request; -import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; -import com.android.volley.toolbox.JsonObjectRequest; -import com.android.volley.toolbox.Volley; +import com.optimalorange.cooltechnologies.BuildConfig; import com.optimalorange.cooltechnologies.R; import com.optimalorange.cooltechnologies.adapter.FavoriteAdapter; import com.optimalorange.cooltechnologies.entity.FavoriteBean; import com.optimalorange.cooltechnologies.network.DestroyFavoriteRequest; +import com.optimalorange.cooltechnologies.network.GetMyFavoriteRequest; import com.optimalorange.cooltechnologies.network.NetworkChecker; import com.optimalorange.cooltechnologies.network.VolleySingleton; import com.optimalorange.cooltechnologies.storage.DefaultSharedPreferencesSingleton; @@ -38,6 +36,8 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; /** * Created by WANGZHENGZE on 2014/11/20. @@ -50,7 +50,6 @@ public class FavoriteFragment extends SwipeRefreshFragment { private String mYoukuClientId; private View v; - private static final String FAVORITE_BASE_URL = "https://openapi.youku.com/v2/videos/favorite/by_me.json"; private ListView favoriteListView; private VolleySingleton mVolleySingleton; private DefaultSharedPreferencesSingleton mDefaultSharedPreferencesSingleton; @@ -263,59 +262,13 @@ public void getJsonData() { if (favoriteListView.getVisibility() == View.GONE) { setHint(R.string.favorite_new_loading); } - String token = mDefaultSharedPreferencesSingleton.retrieveString("access_token", ""); if (mDefaultSharedPreferencesSingleton.hasLoggedIn()) { if (!mNetworkChecker.isConnected()) { setHint(R.string.favorite_hint_no_net); return; } - RequestQueue requestQueue = Volley.newRequestQueue(getActivity()); - String url = FAVORITE_BASE_URL + "?client_id=" + getString(R.string.youku_client_id) + "&access_token=" + token + "&page=" + page + "&count=10"; - JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, new Response.Listener() { - @Override - public void onResponse(JSONObject jsonObject) { - try { - total = jsonObject.getInt("total"); - if (total != 0) { - JSONArray videoArray = jsonObject.getJSONArray("videos"); - int pageCount = videoArray.length(); - currentCount += pageCount; - if (currentCount == total) { - tvViewMore.setEnabled(false); - tvViewMore.setText(getString(R.string.favorite_view_more_last)); - } else { - tvViewMore.setEnabled(true); - tvViewMore.setText(getString(R.string.favorite_view_more)); - page++; - } - for (int i = 0; i < videoArray.length(); i++) { - JSONObject itemObject = videoArray.getJSONObject(i); - if(itemObject.getString("category").equals(DEFAULT_CATEGORY_LABEL)){ - FavoriteBean bean = new FavoriteBean(itemObject); - favoriteBeans.add(bean); - } - } - adapter.notifyDataSetChanged(); - favoriteListView.setVisibility(View.VISIBLE); - if (mTvHint.getVisibility() == View.VISIBLE) { - mTvHint.setVisibility(View.GONE); - } - } else { - setHint(R.string.favorite_no_fav); - } - - setRefreshing(false); - } catch (JSONException e) { - e.printStackTrace(); - } - } - }, new Response.ErrorListener() { - @Override - public void onErrorResponse(VolleyError volleyError) { - volleyError.printStackTrace(); - } - }); - requestQueue.add(jsonObjectRequest); + String token = mDefaultSharedPreferencesSingleton.retrieveString("access_token", ""); + mVolleySingleton.addToRequestQueue(buildGetMyFavoriteRequest(token, page, 10)); } else { setHint(R.string.favorite_hint_no_login); } @@ -370,6 +323,19 @@ private void sendDeleteRequest(String id, final int index) { mVolleySingleton.addToRequestQueue(buildDestroyFavoriteRequest(token, id, index)); } + private GetMyFavoriteRequest buildGetMyFavoriteRequest(String token, int page, int count) { + final GetMyFavoriteRequestHandler handler = + new GetMyFavoriteRequestHandler(new WeakReference<>(this)); + return new GetMyFavoriteRequest.Builder() + .setClient_id(mYoukuClientId) + .setAccess_token(token) + .setPage(page) + .setCount(count) + .setResponseListener(handler) + .setErrorListener(handler) + .build(); + } + /** 创建取消收藏的请求 */ private DestroyFavoriteRequest buildDestroyFavoriteRequest( String token, String videoId, int videoIndexInListView) { @@ -384,6 +350,93 @@ private DestroyFavoriteRequest buildDestroyFavoriteRequest( .build(); } + private static class GetMyFavoriteRequestHandler + implements Response.Listener, Response.ErrorListener { + + private final WeakReference mOwner; + + private GetMyFavoriteRequestHandler(WeakReference owner) { + mOwner = owner; + } + + @Override + public void onErrorResponse(VolleyError error) { + new RuntimeException(error).printStackTrace(); + + //TODO stop refreshing & change hint + } + + @Override + public void onResponse(JSONObject response) { + final FavoriteFragment owner = mOwner.get(); + if (owner != null) { + try { + doHandle(response, owner); + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + + private static void doHandle(JSONObject response, FavoriteFragment owner) + throws JSONException { + FavoriteInfo newFavoriteInfo = convertToFavoriteInfo(response); + + //TODO add addFavoriteInfo method? + owner.total = newFavoriteInfo.total; + if (newFavoriteInfo.total != 0) { + owner.currentCount += newFavoriteInfo.currentReadCountIncludingUnneeded; + if (owner.currentCount == owner.total) { + owner.tvViewMore.setEnabled(false); + owner.tvViewMore.setText(owner.getString(R.string.favorite_view_more_last)); + } else { + if (BuildConfig.DEBUG && owner.currentCount >= owner.total) { + throw new AssertionError("owner.currentCount < owner.total"); + } + owner.tvViewMore.setEnabled(true); + owner.tvViewMore.setText(owner.getString(R.string.favorite_view_more)); + owner.page++;//TODO check newFavoriteInfo.currentPage? + } + + owner.favoriteBeans.addAll(newFavoriteInfo.hasRead); + owner.adapter.notifyDataSetChanged(); + owner.favoriteListView.setVisibility(View.VISIBLE); + if (owner.mTvHint.getVisibility() == View.VISIBLE) { + owner.mTvHint.setVisibility(View.GONE); + } + } else { + owner.setHint(R.string.favorite_no_fav); + } + + owner.setRefreshing(false); + } + + private static FavoriteInfo convertToFavoriteInfo(JSONObject jsonObject) + throws JSONException { + FavoriteInfo favoriteInfo = new FavoriteInfo(); + favoriteInfo.total = jsonObject.getInt("total"); + favoriteInfo.currentPage = jsonObject.getInt("page"); + JSONArray videoArray = jsonObject.getJSONArray("videos"); + favoriteInfo.currentReadCountIncludingUnneeded = videoArray.length(); + favoriteInfo.hasRead = convertNeededVideos(videoArray); + return favoriteInfo; + } + + private static List convertNeededVideos(JSONArray videoArray) + throws JSONException { + List result = new LinkedList<>(); + for (int i = 0; i < videoArray.length(); i++) { + JSONObject itemObject = videoArray.getJSONObject(i); + if (itemObject.getString("category").equals(DEFAULT_CATEGORY_LABEL)) { + FavoriteBean bean = new FavoriteBean(itemObject); + result.add(bean); + } + } + return result; + } + + } + private static class DestroyFavoriteRequestHandler implements Response.Listener, Response.ErrorListener { @@ -432,4 +485,15 @@ public void onResponse(JSONObject response) { } + private static class FavoriteInfo { + + int total; + + int currentPage; + + int currentReadCountIncludingUnneeded; + + List hasRead; + } + } From 6eaf49682fad6ac74f987e68ddb85d3b2d4e17a3 Mon Sep 17 00:00:00 2001 From: Bai Jie Date: Fri, 30 Oct 2015 20:59:31 +0800 Subject: [PATCH 040/120] =?UTF-8?q?=E9=BB=98=E8=AE=A4=E4=B8=BB=E9=A2=98?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E7=BB=A7=E6=89=BFTheme.AppCompat.Light.DarkA?= =?UTF-8?q?ctionBar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/values/styles.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index e10f5db..facd1d5 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -1,7 +1,7 @@ - - - + + - - - - -
当前配置下无法播放视频,您可能需要修改应用配置或者修改系统配置
- - - diff --git a/app/src/main/assets/licenses.html b/app/src/main/assets/licenses.html index d119606..35c94de 100644 --- a/app/src/main/assets/licenses.html +++ b/app/src/main/assets/licenses.html @@ -28,40 +28,6 @@ - -

Notice for:

- -
-The MIT License (MIT)
-
-Copyright (c) 2014 Cristian Perez <http://cpr.name>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
- -

Notice for:

    diff --git a/app/src/main/assets/playvideo.html b/app/src/main/assets/playvideo.html deleted file mode 100644 index edf1c56..0000000 --- a/app/src/main/assets/playvideo.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - 播放视频 - - - - - -
    - - - - - - diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/PlayVideoActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/PlayVideoActivity.java deleted file mode 100644 index 957c812..0000000 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/PlayVideoActivity.java +++ /dev/null @@ -1,518 +0,0 @@ -package com.optimalorange.cooltechnologies.ui; - -import com.optimalorange.cooltechnologies.R; -import com.optimalorange.cooltechnologies.network.NetworkChecker; -import com.optimalorange.cooltechnologies.storage.DefaultSharedPreferencesSingleton; -import com.umeng.analytics.MobclickAgent; - -import android.annotation.TargetApi; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.res.Configuration; -import android.net.ConnectivityManager; -import android.os.Build; -import android.os.Bundle; -import android.provider.Settings; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; -import android.view.WindowManager; -import android.webkit.JavascriptInterface; -import android.webkit.WebChromeClient; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.widget.FrameLayout; -import android.widget.LinearLayout; - -import name.cpr.VideoEnabledWebChromeClient; -import name.cpr.VideoEnabledWebView; - -//TODO 处理横竖屏切换等onConfigurationChange -public class PlayVideoActivity extends LoginableBaseActivity { - - /** - * 应当播放的Video的ID
    - * Type: {@link String} - */ - public static final String EXTRA_KEY_VIDEO_ID = - PlayVideoActivity.class.getName() + ".extra.KEY_VIDEO_ID"; - - /** 正常情况下,{@link android.webkit.WebView WebView}要加载的网页的路径 */ - private static final String URL_PLAY_VIDEO = "file:///android_asset/playvideo.html"; - - /** 由于某些原因不能播放视频时,{@link android.webkit.WebView WebView}要加载的网页的路径 */ - private static final String URL_CANNOT_PLAY_VIDEO - = "file:///android_asset/cannotplayvideo.html"; - - /** 用于重置{@link android.webkit.WebView WebView}的空网页 */ - private static final String URL_BLANK = "about:blank"; - - /** {@link #URL_PLAY_VIDEO}中用到的{@link WebAppInterface WebAppInterface}实例名 */ - private static final String JAVASCRIPT_INTERFACE_GENERIC = "webAppInterface"; - - /** - * {@link #URL_PLAY_VIDEO}中用到的 - * {@link WebAppFullscreenToggleSwitch WebAppFullscreenToggleSwitch}实例名 - */ - private static final String JAVASCRIPT_INTERFACE_FULLSCREEN_TOGGLE_SWITCH = - "webAppFullscreenToggleSwitch"; - - /** - * {@link #URL_CANNOT_PLAY_VIDEO}中用到的 - * {@link OnClickSettingsListener OnClickSettingsListener}实例名 - */ - private static final String JAVASCRIPT_INTERFACE_ON_CLICK_SETTINGS_LISTENER = - "onClickSettingsListener"; - - - private DefaultSharedPreferencesSingleton mDefaultSharedPreferencesSingleton; - - private NetworkChecker mNetworkChecker; - - private BroadcastReceiver mNetworkReceiver; - - /** - * 状态属性:已经加载播放器 - */ - private boolean mPlayerIsLoaded = false; - - private LinearLayout mNonVideoLayout; - - private VideoEnabledWebView mWebView; - - private CustomWebViewClient mWebViewClient; - - private VideoEnabledWebChromeClient mChromeClient; - - //-------------------------------------------------------------------------- - // 初始化属性 - //-------------------------------------------------------------------------- - - { - mNetworkReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - initializeWebView(); - } - }; - } - - //-------------------------------------------------------------------------- - // 覆写Activity的生命周期方法 - //-------------------------------------------------------------------------- - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // 初始化属性 - final String videoIdExtra = getIntent().getStringExtra(EXTRA_KEY_VIDEO_ID); - if (videoIdExtra == null) { - throw new IllegalStateException("Please do intent.putExtra(EXTRA_KEY_VIDEO_ID, vid)"); - } - mDefaultSharedPreferencesSingleton = DefaultSharedPreferencesSingleton.getInstance(this); - mNetworkChecker = NetworkChecker.newInstance(this); - - addLoginStatusChangeListener(new OnLoginStatusChangeListener() { - @Override - public void onLoginStatusChanged(boolean hasLoggedIn) { - invalidateOptionsMenu(); - } - }); - - setContentView(R.layout.activity_play_video); - - mWebView = new VideoEnabledWebView(this); - mNonVideoLayout = (LinearLayout) findViewById(R.id.nonVideoLayout); - ViewGroup videoLayout = (ViewGroup) findViewById(R.id.videoLayout); - View loadingView = - getLayoutInflater().inflate(R.layout.view_loading_video, videoLayout, false); - - addWebViewToNonVideoLayout(); - - // setWebViewClient - mWebViewClient = new CustomWebViewClient(); - mWebView.setWebViewClient(mWebViewClient); - // setWebChromeClient - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { - mChromeClient = new VideoEnabledWebChromeClient( - mNonVideoLayout, videoLayout, loadingView, mWebView); - } else { - final WebAppFullscreenToggleSwitch fullscreenToggleSwitch = - new WebAppFullscreenToggleSwitch(); - //TODO 分析解决安全问题 - mWebView.addJavascriptInterface( - fullscreenToggleSwitch, JAVASCRIPT_INTERFACE_FULLSCREEN_TOGGLE_SWITCH); - mChromeClient = new VideoEnabledWebChromeClient( - mNonVideoLayout, videoLayout, loadingView, mWebView) { - // API level >= 19 时,super.onHideCustomView不会触发callback.onCustomViewHidden, - // 需要覆写以触发此事件方法。 - @Override - public void onHideCustomView() { - super.onHideCustomView(); - if (fullscreenToggleSwitch.mVideoViewContainer != null) { - fullscreenToggleSwitch.callback.onCustomViewHidden(); - } - } - }; - } - mChromeClient.setOnToggledFullscreen( - new VideoEnabledWebChromeClient.ToggledFullscreenCallback() { - @Override - public void toggledFullscreen(boolean fullscreen) { - // Your code to handle the full-screen change, for example showing and hiding the title bar. Example: - if (fullscreen) { - WindowManager.LayoutParams attrs = getWindow().getAttributes(); - attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN; - attrs.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; - getWindow().setAttributes(attrs); - //noinspection all - getWindow().getDecorView() - .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE); - if (getSupportActionBar() != null) { - getSupportActionBar().hide(); - } - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - } else { - WindowManager.LayoutParams attrs = getWindow().getAttributes(); - attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN; - attrs.flags &= ~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; - getWindow().setAttributes(attrs); - //noinspection all - getWindow().getDecorView() - .setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); - if (getSupportActionBar() != null) { - getSupportActionBar().show(); - } - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - } - - } - }); - mWebView.setWebChromeClient(mChromeClient); - // end setWebChromeClient - - // addJavascriptInterface - WebAppInterface webAppInterface = new WebAppInterface() - .setClientId(getString(R.string.youku_client_id)) - .setVid(videoIdExtra); - //TODO 分析解决安全问题 - mWebView.addJavascriptInterface(webAppInterface, JAVASCRIPT_INTERFACE_GENERIC); - mWebView.addJavascriptInterface( - new OnClickSettingsListener(this), JAVASCRIPT_INTERFACE_ON_CLICK_SETTINGS_LISTENER); - } - - @Override - protected void onStart() { - super.onStart(); - registerReceiver( - mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); - initializeWebView(); - } - - @Override - protected void onResume() { - super.onResume(); - MobclickAgent.onPageStart(getClass().getSimpleName()); - mWebView.onResume(); - } - - @Override - protected void onPause() { - mWebView.onPause(); - MobclickAgent.onPageEnd(getClass().getSimpleName()); - super.onPause(); - } - - @Override - protected void onStop() { - unregisterReceiver(mNetworkReceiver); - finalizeWebView(); - super.onStop(); - } - - @Override - protected void onDestroy() { - mChromeClient = null; - mWebViewClient = null; - mNonVideoLayout = null; - if (mWebView != null) { - ViewParent parent = mWebView.getParent(); - if (parent != null) { - ((ViewGroup) parent).removeView(mWebView); - } - mWebView.destroy(); - mWebView = null; - } - mNetworkChecker = null; - mDefaultSharedPreferencesSingleton = null; - super.onDestroy(); - } - - @Override - public void onBackPressed() { - if (mChromeClient.onBackPressed()) { - return; - } - - if (mWebView.canGoBack()) { - mWebView.goBack(); - return; - } - - super.onBackPressed(); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - // readd webview to update its height - if (mNonVideoLayout.indexOfChild(mWebView) >= 0) { // if mWebView is in mNonVideoLayout - mNonVideoLayout.removeView(mWebView); - addWebViewToNonVideoLayout(); - } - } - - //-------------------------------------------------------------------------- - // 新声明方法 - //-------------------------------------------------------------------------- - - private void addWebViewToNonVideoLayout() { - int widthPixels = getResources().getDisplayMetrics().widthPixels; - int heightPixels = getResources().getDisplayMetrics().heightPixels; - int desirableHeight = (int) Math.ceil(widthPixels * 9.0 / 16); - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - desirableHeight <= heightPixels ? desirableHeight : heightPixels, - 0 //WebView的layout_weight设为0,评论等其他View的weight非0,让其他View充满剩余空间 - ); - mNonVideoLayout.addView(mWebView, 0, layoutParams); - } - - private void loadUrlAndClearHistory(String url) { - mWebViewClient.shouldClearHistory(true); - mWebView.loadUrl(url); - } - - /** - * 如果条件允许的话,加载播放器;否则,加载{@link #URL_CANNOT_PLAY_VIDEO} - * - * @return {@link #mPlayerIsLoaded} - */ - private boolean initializeWebView() { - boolean loadPlayer = canPlayNow(); - if (loadPlayer) { - if (!mPlayerIsLoaded) { - loadUrlAndClearHistory(URL_PLAY_VIDEO); - } - } else { - loadUrlAndClearHistory(URL_CANNOT_PLAY_VIDEO); - } - mPlayerIsLoaded = loadPlayer; - return loadPlayer; - } - - private void finalizeWebView() { - loadUrlAndClearHistory(URL_BLANK); - mPlayerIsLoaded = false; - } - - private boolean canPlayNow() { - if (mDefaultSharedPreferencesSingleton.onlyPlayVideoWhenUseWlan()) { - return mNetworkChecker.isWifiConnected(); - } else { - return mNetworkChecker.isConnected(); - } - } - - //-------------------------------------------------------------------------- - // 嵌套类 - //-------------------------------------------------------------------------- - - //------------------------------------- - // WebViewClient - //------------------------------------- - - private static class CustomWebViewClient extends WebViewClient { - - // 参考自 http://stackoverflow.com/questions/8103532/how-to-clear-webview-history-in-android#20657089 - private boolean mShouldClearHistory = false; - - public void shouldClearHistory(boolean shouldClearHistory) { - mShouldClearHistory = shouldClearHistory; - } - - @Override - public void onPageFinished(WebView view, String url) { - super.onPageFinished(view, url); - if (mShouldClearHistory) { - view.clearHistory(); - mShouldClearHistory = false; - } - } - } - - //------------------------------------- - // JavascriptInterface - //------------------------------------- - - /** - * {@link android.webkit.WebView WebView}中网页可以访问的本地API,用于设置参数,如 - * {@link WebAppInterface#getVid() vid}
    - * 本类是线程安全的 - */ - private static class WebAppInterface { - - /** 控制条底色:明;主色板颜色:橘色 */ - private static final String DEFAULT_STYLE_ID = "8"; - - // important! must be **volatile** - private volatile String mTitle = ""; - - private volatile String mStyleId = DEFAULT_STYLE_ID; - - private volatile String mClientId; - - /** Video ID */ - private volatile String mVid; - - private volatile boolean mAutoplay = false; - - private volatile boolean mShowRelated = false; - - public WebAppInterface setTitle(String title) { - mTitle = title; - return this; - } - - public WebAppInterface setStyleId(String styleId) { - mStyleId = styleId; - return this; - } - - public WebAppInterface setClientId(String clientId) { - mClientId = clientId; - return this; - } - - public WebAppInterface setVid(String vid) { - mVid = vid; - return this; - } - - public WebAppInterface setAutoplay(boolean autoplay) { - mAutoplay = autoplay; - return this; - } - - public WebAppInterface setShowRelated(boolean showRelated) { - mShowRelated = showRelated; - return this; - } - - @JavascriptInterface - public String getTitle() { - return mTitle; - } - - @JavascriptInterface - public String getStyleId() { - return mStyleId; - } - - @JavascriptInterface - public String getClientId() { - return mClientId; - } - - @JavascriptInterface - public String getVid() { - return mVid; - } - - @JavascriptInterface - public boolean isAutoplay() { - return mAutoplay; - } - - @JavascriptInterface - public boolean isShowRelated() { - return mShowRelated; - } - } - - /** - * 在{@link Build.VERSION_CODES#KITKAT}以上版本,点击{@link #URL_PLAY_VIDEO}中视屏全屏按钮时, - * 触发本类的实例的{@link PlayVideoActivity.WebAppFullscreenToggleSwitch#toggleFullscreen()}方法。 - */ - @TargetApi(Build.VERSION_CODES.KITKAT) - private class WebAppFullscreenToggleSwitch { - - private FrameLayout mVideoViewContainer; - - private final WebChromeClient.CustomViewCallback callback = - new WebChromeClient.CustomViewCallback() { - @Override - public void onCustomViewHidden() { - if (mVideoViewContainer != null) { - mVideoViewContainer.removeView(mWebView); - addWebViewToNonVideoLayout(); - // release memory - mVideoViewContainer = null; - } - } - }; - - /** - * 触发全屏与非全屏状态间的切换。 - */ - @JavascriptInterface - public void toggleFullscreen() { - PlayVideoActivity.this.runOnUiThread(new Runnable() { - @Override - public void run() { - if (!mChromeClient.isVideoFullscreen()) { - assert mVideoViewContainer == null; - mNonVideoLayout.removeView(mWebView); - mVideoViewContainer = new FrameLayout(PlayVideoActivity.this); - mVideoViewContainer.addView( - mWebView, - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - ); - mChromeClient.onShowCustomView(mVideoViewContainer, callback); - } else { - mChromeClient.onHideCustomView(); - // see also WebAppFullscreenToggleSwitch.callback - } - } - }); - } - } - - /** - * 点击{@link WebView}中的“修改系统配置”、“修改应用配置”等时被调用。 - */ - private static class OnClickSettingsListener { - - private final Context mContext; - - private OnClickSettingsListener(Context context) { - mContext = context; - } - - @JavascriptInterface - public void onClickAppSettings() { - mContext.startActivity(new Intent(mContext, SettingsActivity.class)); - } - - @JavascriptInterface - public void onClickSystemSettings() { - mContext.startActivity(new Intent(Settings.ACTION_SETTINGS)); - } - } - -} diff --git a/app/src/main/res/layout/activity_play_video.xml b/app/src/main/res/layout/activity_play_video.xml deleted file mode 100644 index 11666f2..0000000 --- a/app/src/main/res/layout/activity_play_video.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/view_loading_video.xml b/app/src/main/res/layout/view_loading_video.xml deleted file mode 100644 index 4b588a5..0000000 --- a/app/src/main/res/layout/view_loading_video.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 22c95fd..95e3324 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -39,10 +39,6 @@ 正在加载中,请稍后…… 还没有历史记录哦~~ - - 播放 - 加载视频… - 搜索 From cd2d950ab1d14790199083b2a50de9653a04a672 Mon Sep 17 00:00:00 2001 From: Bai Jie Date: Sun, 22 Nov 2015 09:35:54 +0800 Subject: [PATCH 092/120] =?UTF-8?q?=E6=9B=B4=E6=96=B0Gradle=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a08965c..dae2c7f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Nov 08 11:39:49 CST 2015 +#Sun Nov 22 09:32:47 CST 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-bin.zip From 4b2d00de4b7a21422dbc631756ddfc124c8e6ff8 Mon Sep 17 00:00:00 2001 From: Zhou-Peican Date: Sun, 22 Nov 2015 15:53:19 +0800 Subject: [PATCH 093/120] =?UTF-8?q?=E7=83=AD=E9=97=A8=E9=A1=B5=E5=92=8C?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E9=A1=B5=E5=8A=A0=E8=BD=BD=E6=9B=B4=E5=A4=9A?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=E6=94=B9=E5=8F=98=EF=BC=8C=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E4=BA=86=E5=BA=95=E9=83=A8=E7=9B=91=E5=90=AC=E4=B8=94=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=8A=A0=E8=BD=BD=E6=97=B6=E6=98=BE=E7=A4=BAprogressb?= =?UTF-8?q?ar=20#21?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 1 + .../listener/OnBottomListener.java | 7 ++ .../OnRecyclerViewScrollListener.java | 93 +++++++++++++++++++ .../cooltechnologies/ui/SearchActivity.java | 46 +++++++-- .../ui/fragment/FavoriteFragment.java | 2 +- .../ui/fragment/ListVideosFragment.java | 45 ++++++++- app/src/main/res/layout/activity_search.xml | 25 +++-- .../main/res/layout/fragment_list_videos.xml | 12 +++ app/src/main/res/values/strings.xml | 4 +- 9 files changed, 216 insertions(+), 19 deletions(-) create mode 100644 app/src/main/java/com/optimalorange/cooltechnologies/listener/OnBottomListener.java create mode 100644 app/src/main/java/com/optimalorange/cooltechnologies/listener/OnRecyclerViewScrollListener.java diff --git a/app/build.gradle b/app/build.gradle index 9883896..db00437 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -96,6 +96,7 @@ dependencies { compile 'gq.baijie:classbasedviewadapter:0.1.0' compile 'com.umeng.update:library:2.5.0' compile 'com.umeng.analytics:library:5.4.1' + compile 'me.zhanghai.android.materialprogressbar:library:1.1.4' } // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 代码质量检查 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnBottomListener.java b/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnBottomListener.java new file mode 100644 index 0000000..7bced5d --- /dev/null +++ b/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnBottomListener.java @@ -0,0 +1,7 @@ +package com.optimalorange.cooltechnologies.listener; + + +public interface OnBottomListener { + + public void onBottom(); +} diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnRecyclerViewScrollListener.java b/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnRecyclerViewScrollListener.java new file mode 100644 index 0000000..ff394a0 --- /dev/null +++ b/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnRecyclerViewScrollListener.java @@ -0,0 +1,93 @@ +package com.optimalorange.cooltechnologies.listener; + + +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.StaggeredGridLayoutManager; + +public class OnRecyclerViewScrollListener extends RecyclerView.OnScrollListener + implements OnBottomListener { + + public enum LAYOUT_MANAGER_TYPE { + LINEAR, + STAGGERED_GRID + } + + protected LAYOUT_MANAGER_TYPE layoutManagerType; + + /** + * 最后一个的位置 + */ + private int[] lastPositions; + + /** + * 最后一个可见的item的位置 + */ + private int lastVisibleItemPosition; + + /** + * 当前滑动的状态 + */ + private int currentScrollState = 0; + + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); + + // GridLayoutManager 是 LinearLayoutManager子类,且获取最后一个可见item位置方法是一样的 + if (layoutManagerType == null) { + if (layoutManager instanceof LinearLayoutManager) { + layoutManagerType = LAYOUT_MANAGER_TYPE.LINEAR; + } else if (layoutManager instanceof StaggeredGridLayoutManager) { + layoutManagerType = LAYOUT_MANAGER_TYPE.STAGGERED_GRID; + } else { + throw new RuntimeException( + "Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager"); + } + } + + switch (layoutManagerType) { + case LINEAR: + lastVisibleItemPosition = ((LinearLayoutManager) layoutManager) + .findLastVisibleItemPosition(); + break; + case STAGGERED_GRID: + StaggeredGridLayoutManager staggeredGridLayoutManager + = (StaggeredGridLayoutManager) layoutManager; + if (lastPositions == null) { + lastPositions = new int[staggeredGridLayoutManager.getSpanCount()]; + } + staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions); + lastVisibleItemPosition = findMax(lastPositions); + break; + } + } + + private int findMax(int[] lastPositions) { + int max = lastPositions[0]; + for (int value : lastPositions) { + if (value > max) { + max = value; + } + } + return max; + } + + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); + currentScrollState = newState; + RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); + int visibleItemCount = layoutManager.getChildCount(); + int totalItemCount = layoutManager.getItemCount(); + if (visibleItemCount > 0 && currentScrollState == RecyclerView.SCROLL_STATE_IDLE && + lastVisibleItemPosition >= totalItemCount - 1) { + onBottom(); + } + } + + @Override + public void onBottom() { + } +} diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/SearchActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/SearchActivity.java index 61485f4..bf30eba 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/SearchActivity.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/SearchActivity.java @@ -5,6 +5,7 @@ import com.android.volley.toolbox.ImageLoader; import com.optimalorange.cooltechnologies.R; import com.optimalorange.cooltechnologies.entity.Video; +import com.optimalorange.cooltechnologies.listener.OnRecyclerViewScrollListener; import com.optimalorange.cooltechnologies.network.SearchRequest; import com.optimalorange.cooltechnologies.network.VolleySingleton; import com.optimalorange.cooltechnologies.util.Utils; @@ -25,14 +26,16 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; import java.util.LinkedList; import java.util.List; +import me.zhanghai.android.materialprogressbar.MaterialProgressBar; + /** * 搜索页面 * - * @author Zhou Peican */ public class SearchActivity extends BaseActivity { @@ -54,6 +57,13 @@ public class SearchActivity extends BaseActivity { private LinkedList diff --git a/app/src/main/res/layout/fragment_list_videos.xml b/app/src/main/res/layout/fragment_list_videos.xml index 34936ca..86f549d 100644 --- a/app/src/main/res/layout/fragment_list_videos.xml +++ b/app/src/main/res/layout/fragment_list_videos.xml @@ -1,6 +1,7 @@ + + 搜索 输入关键词搜索 + + 已经是最后一个了 + 打开网络设置 网络连接不可用,现在打开网络开关? @@ -33,7 +36,6 @@ 删除历史记录成功 删除收藏失败 点击查看更多 - 已经是最后一个了 正在加载中… 还没有收藏哦~~点我可以刷新 正在加载中,请稍后…… From e17f0a275e2c4c0a9c08344d1cdab3a066d71736 Mon Sep 17 00:00:00 2001 From: Zhou-Peican Date: Sun, 22 Nov 2015 17:48:39 +0800 Subject: [PATCH 094/120] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AF=81=E4=B9=A6?= =?UTF-8?q?=EF=BC=9Ame.zhanghai.android.materialprogressbar:library?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...anghai.android.materialprogressbar.LICENSE | 0 app/src/main/assets/licenses.html | 27 ++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 app/libs/licenses/me.zhanghai.android.materialprogressbar.LICENSE diff --git a/app/libs/licenses/me.zhanghai.android.materialprogressbar.LICENSE b/app/libs/licenses/me.zhanghai.android.materialprogressbar.LICENSE new file mode 100644 index 0000000..e69de29 diff --git a/app/src/main/assets/licenses.html b/app/src/main/assets/licenses.html index 35c94de..8060a9d 100644 --- a/app/src/main/assets/licenses.html +++ b/app/src/main/assets/licenses.html @@ -27,7 +27,6 @@ -

    Notice for:

      @@ -647,6 +646,32 @@

      Notice for:

+ +

Notice for:

+ +
+Copyright 2015 Zhang Hai
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+ From 0f907d0fa23743c793c5c771cc0e52c8580d6c89 Mon Sep 17 00:00:00 2001 From: Zhou-Peican Date: Sun, 22 Nov 2015 17:53:38 +0800 Subject: [PATCH 095/120] =?UTF-8?q?=E8=A1=A5=E4=BF=AE=EF=BC=9A4b2d00de4b7a?= =?UTF-8?q?21422dbc631756ddfc124c8e6ff8=EF=BC=9B=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E6=97=B6=E9=87=8D=E6=96=B0=E8=AE=BE=E7=BD=AERecyclerview?= =?UTF-8?q?=E7=9B=91=E5=90=AC=EF=BC=8COnRecyclerViewScrollListener.java?= =?UTF-8?q?=E9=83=BD=E5=9C=A8onScrolled=E6=93=8D=E4=BD=9C=20#21?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...anghai.android.materialprogressbar.LICENSE | 16 ++++++++++ .../OnRecyclerViewScrollListener.java | 32 ++++++------------- .../ui/fragment/ListVideosFragment.java | 1 + 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/app/libs/licenses/me.zhanghai.android.materialprogressbar.LICENSE b/app/libs/licenses/me.zhanghai.android.materialprogressbar.LICENSE index e69de29..2ef0847 100644 --- a/app/libs/licenses/me.zhanghai.android.materialprogressbar.LICENSE +++ b/app/libs/licenses/me.zhanghai.android.materialprogressbar.LICENSE @@ -0,0 +1,16 @@ +Notice for: + me.zhanghai.android.materialprogressbar:library:1.1.4 +------------------------------------------------------------ +Copyright 2015 Zhang Hai + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnRecyclerViewScrollListener.java b/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnRecyclerViewScrollListener.java index ff394a0..725fcf8 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnRecyclerViewScrollListener.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnRecyclerViewScrollListener.java @@ -8,12 +8,12 @@ public class OnRecyclerViewScrollListener extends RecyclerView.OnScrollListener implements OnBottomListener { - public enum LAYOUT_MANAGER_TYPE { + public enum LayoutManagerType { LINEAR, STAGGERED_GRID } - protected LAYOUT_MANAGER_TYPE layoutManagerType; + protected LayoutManagerType layoutManagerType; /** * 最后一个的位置 @@ -25,11 +25,6 @@ public enum LAYOUT_MANAGER_TYPE { */ private int lastVisibleItemPosition; - /** - * 当前滑动的状态 - */ - private int currentScrollState = 0; - @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); @@ -38,9 +33,9 @@ public void onScrolled(RecyclerView recyclerView, int dx, int dy) { // GridLayoutManager 是 LinearLayoutManager子类,且获取最后一个可见item位置方法是一样的 if (layoutManagerType == null) { if (layoutManager instanceof LinearLayoutManager) { - layoutManagerType = LAYOUT_MANAGER_TYPE.LINEAR; + layoutManagerType = LayoutManagerType.LINEAR; } else if (layoutManager instanceof StaggeredGridLayoutManager) { - layoutManagerType = LAYOUT_MANAGER_TYPE.STAGGERED_GRID; + layoutManagerType = LayoutManagerType.STAGGERED_GRID; } else { throw new RuntimeException( "Unsupported LayoutManager used. Valid ones are LinearLayoutManager, GridLayoutManager and StaggeredGridLayoutManager"); @@ -62,6 +57,12 @@ public void onScrolled(RecyclerView recyclerView, int dx, int dy) { lastVisibleItemPosition = findMax(lastPositions); break; } + + int visibleItemCount = layoutManager.getChildCount(); + int totalItemCount = layoutManager.getItemCount(); + if (visibleItemCount > 0 && lastVisibleItemPosition >= totalItemCount - 1) { + onBottom(); + } } private int findMax(int[] lastPositions) { @@ -74,19 +75,6 @@ private int findMax(int[] lastPositions) { return max; } - @Override - public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - super.onScrollStateChanged(recyclerView, newState); - currentScrollState = newState; - RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); - int visibleItemCount = layoutManager.getChildCount(); - int totalItemCount = layoutManager.getItemCount(); - if (visibleItemCount > 0 && currentScrollState == RecyclerView.SCROLL_STATE_IDLE && - lastVisibleItemPosition >= totalItemCount - 1) { - onBottom(); - } - } - @Override public void onBottom() { } diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListVideosFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListVideosFragment.java index d014afa..a28c146 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListVideosFragment.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListVideosFragment.java @@ -289,6 +289,7 @@ public void onRefresh() { mPage = 1; mAdapter.notifyDataSetChanged(); restartLoad(); + initListener(); } @Override From 414d09d70a1e18e5a5fbce7078cd775ea2042b03 Mon Sep 17 00:00:00 2001 From: Bai Jie Date: Sun, 22 Nov 2015 18:31:32 +0800 Subject: [PATCH 096/120] =?UTF-8?q?HistoryFragment=E6=8D=A2=E7=94=A8Recycl?= =?UTF-8?q?erView?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改 HistoryFragment换用RecyclerView 修改 DBManager.getAllHistory()的返回类型改为List
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 7273455..90c0b71 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -30,15 +30,7 @@ 8sp 10sp - 15dp - 10dp - 100dp - 100dp - 10dp - - 6dp 3dp - 5dp 10dp From 9bc6d09268cc06769ec44051545b945f129eec68 Mon Sep 17 00:00:00 2001 From: Bai Jie Date: Fri, 27 Nov 2015 18:45:28 +0800 Subject: [PATCH 105/120] =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84FavoriteBean?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cooltechnologies/entity/FavoriteBean.java | 36 ------------------- .../storage/sqlite/DBManager.java | 19 +++++----- .../ui/ShowVideoDetailActivity.java | 14 +------- 3 files changed, 10 insertions(+), 59 deletions(-) delete mode 100644 app/src/main/java/com/optimalorange/cooltechnologies/entity/FavoriteBean.java diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/entity/FavoriteBean.java b/app/src/main/java/com/optimalorange/cooltechnologies/entity/FavoriteBean.java deleted file mode 100644 index ffb7415..0000000 --- a/app/src/main/java/com/optimalorange/cooltechnologies/entity/FavoriteBean.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.optimalorange.cooltechnologies.entity; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.Serializable; - -/** - * Created by WANGZHENGZE on 2014/11/29. - */ -public class FavoriteBean implements Serializable { - public String title = ""; - public String imageUrl = ""; - public String duration = ""; - public String link = ""; - public String videoId = ""; - - public FavoriteBean(){} - - public FavoriteBean(Video video){ - title = video.getTitle(); - imageUrl = video.getThumbnail(); - duration = String.valueOf(video.getDuration()); - link = video.getLink(); - videoId = video.getId(); - } - - public FavoriteBean(JSONObject jsonObject) throws JSONException { - title = jsonObject.getString("title"); - link = jsonObject.getString("link"); - imageUrl = jsonObject.getString("thumbnail"); - duration = jsonObject.getString("duration"); - videoId = jsonObject.getString("id"); - } - -} diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/storage/sqlite/DBManager.java b/app/src/main/java/com/optimalorange/cooltechnologies/storage/sqlite/DBManager.java index bbfc65e..e2ab47b 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/storage/sqlite/DBManager.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/storage/sqlite/DBManager.java @@ -1,6 +1,5 @@ package com.optimalorange.cooltechnologies.storage.sqlite; -import com.optimalorange.cooltechnologies.entity.FavoriteBean; import com.optimalorange.cooltechnologies.ui.entity.Video; import android.content.ContentValues; @@ -84,13 +83,13 @@ public boolean isOpen() { return db != null && db.isOpen(); } - public void saveHistory(FavoriteBean bean) { + public void saveHistory(Video bean) { open(); final ContentValues contentValues = convertToContentValues(bean); db.beginTransaction(); try { - if (isInHistory(bean.videoId)) { - deleteHistory(bean.videoId); + if (isInHistory(bean.id)) { + deleteHistory(bean.id); } db.insert("history", null, contentValues); @@ -127,13 +126,13 @@ public int deleteHistory(String videoId) { return db.delete("history", "_videoId = ?", new String[]{videoId}); } - private static ContentValues convertToContentValues(FavoriteBean favoriteBean) { + private static ContentValues convertToContentValues(Video video) { final ContentValues contentValues = new ContentValues(); - contentValues.put("_videoId", favoriteBean.videoId); - contentValues.put("_title", favoriteBean.title); - contentValues.put("_duration", favoriteBean.duration); - contentValues.put("_imageUrl", favoriteBean.imageUrl); - contentValues.put("_link", favoriteBean.link); + contentValues.put("_videoId", video.id); + contentValues.put("_title", video.title); + contentValues.put("_duration", video.duration); + contentValues.put("_imageUrl", video.thumbnail); + contentValues.put("_link", video.link); return contentValues; } diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/ShowVideoDetailActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/ShowVideoDetailActivity.java index e128b2e..d7fc9d5 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/ShowVideoDetailActivity.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/ShowVideoDetailActivity.java @@ -4,7 +4,6 @@ import com.android.volley.VolleyError; import com.android.volley.toolbox.ImageLoader; import com.optimalorange.cooltechnologies.R; -import com.optimalorange.cooltechnologies.entity.FavoriteBean; import com.optimalorange.cooltechnologies.network.CreateFavoriteRequest; import com.optimalorange.cooltechnologies.network.DestroyFavoriteRequest; import com.optimalorange.cooltechnologies.network.NetworkChecker; @@ -92,23 +91,12 @@ public void playVideo() { throw new IllegalStateException("cannot play video before load it."); } - final FavoriteBean favoriteBean = convertToFavoriteBean(mVideo); // 保存播放历史 - DBManager.getInstance(this).saveHistory(favoriteBean); + DBManager.getInstance(this).saveHistory(mVideo); // 跳转到 SimpleWebViewActivity SimpleWebViewActivity.start(this, mVideo.link); } - private static FavoriteBean convertToFavoriteBean(Video video) { - final FavoriteBean result = new FavoriteBean(); - result.videoId = video.id; - result.title = video.title; - result.duration = video.duration; - result.imageUrl = video.bigThumbnail; - result.link = video.link; - return result; - } - /** * 有新添加的菜单项 */ From 418ed41a24a261d84fa98b762c12f0df64de7b27 Mon Sep 17 00:00:00 2001 From: Bai Jie Date: Fri, 27 Nov 2015 18:57:24 +0800 Subject: [PATCH 106/120] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E7=9A=84Video.bigThumbnail=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cooltechnologies/ui/ShowVideoDetailActivity.java | 5 ++--- .../com/optimalorange/cooltechnologies/ui/entity/Video.java | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/ShowVideoDetailActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/ShowVideoDetailActivity.java index d7fc9d5..0ec187c 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/ShowVideoDetailActivity.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/ShowVideoDetailActivity.java @@ -82,7 +82,7 @@ public void onClick(View v) { final ImageLoader.ImageListener imageListener = ImageLoader.getImageListener( mViews.thumbnail, 0, 0 ); - mVolleySingleton.getImageLoader().get(video.bigThumbnail, imageListener); + mVolleySingleton.getImageLoader().get(video.thumbnail, imageListener); } } @@ -265,8 +265,7 @@ private static Video convertToVideo(JSONObject jsonObject) throws JSONException result.id = jsonObject.getString("id"); result.title = jsonObject.getString("title"); result.link = jsonObject.getString("link"); - result.thumbnail = jsonObject.getString("thumbnail"); - result.bigThumbnail = jsonObject.getString("bigThumbnail"); + result.thumbnail = jsonObject.getString("bigThumbnail"); result.duration = jsonObject.getString("duration"); result.description = jsonObject.getString("description"); return result; diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/entity/Video.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/entity/Video.java index 7366d4e..f33313c 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/entity/Video.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/entity/Video.java @@ -15,8 +15,6 @@ public class Video { */ public String thumbnail; - public String bigThumbnail; - public String description; } From a8ef83762b07eefaceb9c9e3cb3c4198d2d9fa82 Mon Sep 17 00:00:00 2001 From: Bai Jie Date: Fri, 27 Nov 2015 20:13:10 +0800 Subject: [PATCH 107/120] =?UTF-8?q?=E6=9B=B4=E6=96=B0Android=20Gradle=20Bu?= =?UTF-8?q?ild=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改 更新Android Gradle Build插件 修改 暂时通过jitpack.io,使用最新版android-sdk-manager Gradle插件,以兼容新版Android Gradle Build插件 --- app/build.gradle | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9883896..77e9eb2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,10 +2,11 @@ buildscript { repositories { mavenCentral() jcenter() + maven { url "https://jitpack.io" } } dependencies { - classpath 'com.android.tools.build:gradle:1.5.0' - classpath 'com.jakewharton.sdkmanager:gradle-plugin:0.12.0' + classpath 'com.android.tools.build:gradle:2.0.0-alpha1' + classpath 'com.github.JakeWharton:sdk-manager-plugin:220bf7a88a' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } From bc24e57f673b290daa6b4eb533417f0d1ef924da Mon Sep 17 00:00:00 2001 From: Zhou-Peican Date: Sun, 29 Nov 2015 10:27:00 +0800 Subject: [PATCH 108/120] =?UTF-8?q?=E6=90=9C=E7=B4=A2=E9=A1=B5=E7=9A=84pro?= =?UTF-8?q?gressbar=E8=B4=B4=E5=88=B0=E5=BA=95=E9=83=A8=20#21?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/activity_search.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/activity_search.xml b/app/src/main/res/layout/activity_search.xml index 4f0d906..3913e73 100644 --- a/app/src/main/res/layout/activity_search.xml +++ b/app/src/main/res/layout/activity_search.xml @@ -21,7 +21,8 @@ android:layout_gravity="bottom" android:indeterminate="true" app:mpb_progressStyle="horizontal" - style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal" + app:mpb_useIntrinsicPadding="false" + style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal.NoPadding" android:visibility="gone" /> From be24a39b0e9d51292eb59e76a92c1b12239f958f Mon Sep 17 00:00:00 2001 From: Bai Jie Date: Fri, 27 Nov 2015 19:35:38 +0800 Subject: [PATCH 109/120] =?UTF-8?q?=E6=B6=88=E9=99=A4=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=E4=B8=AD=E9=A2=84=E8=A7=88=E5=9B=BE?= =?UTF-8?q?=E4=B8=A4=E8=BE=B9=E7=9A=84=E6=A9=98=E8=89=B2=E7=BA=BF=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 视频详情页显示预览图时,设置其背景为黑色,以消除两边的橘色(?attr/colorPrimary)线条 --- .../ui/ShowVideoDetailActivity.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/ShowVideoDetailActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/ShowVideoDetailActivity.java index 0ec187c..22f6d08 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/ShowVideoDetailActivity.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/ShowVideoDetailActivity.java @@ -82,7 +82,18 @@ public void onClick(View v) { final ImageLoader.ImageListener imageListener = ImageLoader.getImageListener( mViews.thumbnail, 0, 0 ); - mVolleySingleton.getImageLoader().get(video.thumbnail, imageListener); + final ImageLoader.ImageListener imageListenerWrapper = new ImageLoader.ImageListener() { + @Override + public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) { + imageListener.onResponse(response, isImmediate); + mViews.thumbnail.setBackgroundResource(R.color.black); + } + @Override + public void onErrorResponse(VolleyError error) { + imageListener.onErrorResponse(error); + } + }; + mVolleySingleton.getImageLoader().get(video.thumbnail, imageListenerWrapper); } } From ecf141ea2fc061d2f7e80b47d26a816657f90707 Mon Sep 17 00:00:00 2001 From: Zhou-Peican Date: Sun, 29 Nov 2015 12:01:40 +0800 Subject: [PATCH 110/120] =?UTF-8?q?=EF=BB=BF=E7=83=AD=E9=97=A8=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E6=A0=B9=E6=8D=AE=E5=BD=93=E5=A4=A9=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E9=87=8F=E8=8E=B7=E5=8F=96=EF=BC=8C=E7=B1=BB=E5=9E=8B=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E6=A0=B9=E6=8D=AE=E6=9C=AC=E5=91=A8=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E9=87=8F=E8=8E=B7=E5=8F=96=20fixed=20#24=20=E6=8F=90=E9=AB=98?= =?UTF-8?q?=E4=B8=BB=E9=A1=B5=E5=86=85=E5=AE=B9=E6=9B=B4=E6=96=B0=E9=80=9F?= =?UTF-8?q?=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cooltechnologies/ui/fragment/ListGenresFragment.java | 2 +- .../cooltechnologies/ui/fragment/ListVideosFragment.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListGenresFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListGenresFragment.java index 44f13ce..38251e2 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListGenresFragment.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListGenresFragment.java @@ -162,7 +162,7 @@ private Request buildQueryVideosRequest(final String genre, .setClient_id(mYoukuClientId) .setCategory(CATEGORY_LABEL_OF_TECH) .setGenre(genre) - .setPeriod(VideosRequest.Builder.PERIOD.MONTH) + .setPeriod(VideosRequest.Builder.PERIOD.WEEK) .setCount(mItemsCountAndDimension.getCount()) .setResponseListener(new Response.Listener>() { @Override diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListVideosFragment.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListVideosFragment.java index 525d0e6..bf9e6ac 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListVideosFragment.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/fragment/ListVideosFragment.java @@ -102,7 +102,7 @@ private VideosRequest buildQueryVideosRequest() { .setClient_id(mYoukuClientId) .setCategory(CATEGORY_LABEL_OF_TECH) .setPage(mPage) - .setPeriod(VideosRequest.Builder.PERIOD.WEEK) + .setPeriod(VideosRequest.Builder.PERIOD.TODAY) .setOrderby(VideosRequest.Builder.ORDER_BY.VIEW_COUNT) .setResponseListener(new Response.Listener>() { @Override From 2b94c55dab0e5e55e37667dee396f8c2f3b21667 Mon Sep 17 00:00:00 2001 From: Zhou-Peican Date: Sun, 29 Nov 2015 15:04:34 +0800 Subject: [PATCH 111/120] =?UTF-8?q?=EF=BB=BFOnRecyclerViewScrollListener?= =?UTF-8?q?=E4=B8=AD=E7=9A=84LayoutManagerType=E6=94=B9=E4=B8=BAprivate?= =?UTF-8?q?=EF=BC=9BmPage=E6=94=BE=E5=88=B0=E8=AF=B7=E6=B1=82=E6=88=90?= =?UTF-8?q?=E5=8A=9F=E8=BF=94=E5=9B=9E=E7=9A=84=E5=9C=B0=E6=96=B9=EF=BC=9B?= =?UTF-8?q?mIsQueryingVideos=E4=BA=8Eprogressbar=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=EF=BC=9BonDestroy=E4=B8=AD=E7=9A=84removeListener=E4=B8=AD?= =?UTF-8?q?=E6=9C=89null=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listener/OnRecyclerViewScrollListener.java | 2 +- .../cooltechnologies/ui/SearchActivity.java | 10 ++++------ .../ui/fragment/ListVideosFragment.java | 12 +++++------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnRecyclerViewScrollListener.java b/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnRecyclerViewScrollListener.java index 7d9b9a4..e86b149 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnRecyclerViewScrollListener.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/listener/OnRecyclerViewScrollListener.java @@ -8,7 +8,7 @@ public class OnRecyclerViewScrollListener extends RecyclerView.OnScrollListener implements OnBottomListener { - public enum LayoutManagerType { + private enum LayoutManagerType { LINEAR, STAGGERED_GRID } diff --git a/app/src/main/java/com/optimalorange/cooltechnologies/ui/SearchActivity.java b/app/src/main/java/com/optimalorange/cooltechnologies/ui/SearchActivity.java index b0d4ae9..f684cb7 100644 --- a/app/src/main/java/com/optimalorange/cooltechnologies/ui/SearchActivity.java +++ b/app/src/main/java/com/optimalorange/cooltechnologies/ui/SearchActivity.java @@ -81,6 +81,8 @@ public void onResponse(List