├── libs ├── android-support-v4.jar ├── android-support-v7-appcompat.jar └── android-support-v7-recyclerview.jar ├── AndroidManifest.xml ├── src └── com │ └── wangjie │ └── androidbucket │ ├── customviews │ ├── sublayout │ │ └── ISubLayout.java │ ├── horizontialmenu │ │ ├── OnHoriMenuItemListener.java │ │ └── HorizontialMenu.java │ ├── borderscrollview │ │ ├── OnScrollChangedListener.java │ │ ├── OnScrollChangedListenerSimple.java │ │ └── BorderScrollView.java │ ├── dropdownmenu │ │ ├── IDropMenu.java │ │ ├── DropMenuAdapter.java │ │ ├── DropMenu.java │ │ └── common │ │ │ └── CommonDropMenu.java │ ├── horizontalgallery │ │ └── HorizontalGalleryBaseAdapter.java │ ├── drawable │ │ ├── CornerDrawable.java │ │ ├── InnerBorderDrawable.java │ │ └── CircleDrawable.java │ ├── NestedGridView.java │ ├── verticalmenu │ │ ├── SheetItem.java │ │ ├── SheetAdapter.java │ │ └── SheetComplexAdapter.java │ ├── VerticalScrollView.java │ ├── TextCopy.java │ ├── WrapContentHeightViewPager.java │ ├── pinnedexpandablelistview │ │ └── PinnedBaseExpandableAdapter.java │ └── NestedListView.java │ ├── core │ ├── collecion │ │ ├── KeySort.java │ │ ├── LanguageComparator_EN.java │ │ ├── PinyinKeySortable.java │ │ └── HashList.java │ └── file │ │ └── utils │ │ └── FileDownloadUtil.java │ ├── mvp │ ├── ABNonePresenterImpl.java │ ├── ABInteractor.java │ ├── ABNoneInteractorImpl.java │ ├── TaskController.java │ ├── ABBaseTaskManager.java │ ├── ABActivityViewer.java │ └── ABBasePresenter.java │ ├── services │ ├── BaseAccessResponse.java │ ├── network │ │ ├── http │ │ │ ├── ABHttpMethod.java │ │ │ ├── interceptor │ │ │ │ └── HttpMethodInterceptor.java │ │ │ ├── HttpConstants.java │ │ │ ├── HttpConfig.java │ │ │ └── SSLSocketFactoryEx.java │ │ ├── exception │ │ │ ├── ServerError.java │ │ │ ├── RetryFailedException.java │ │ │ └── HippoException.java │ │ ├── Network.java │ │ ├── RequestListener.java │ │ ├── interceptor │ │ │ └── Interceptor.java │ │ ├── DispatchRequestListener.java │ │ ├── RetryPolicy.java │ │ ├── NetworkResponse.java │ │ ├── HippoResponse.java │ │ ├── HippoRequestQueue.java │ │ └── toolbox │ │ │ ├── PoolingByteArrayOutputStream.java │ │ │ └── StringHippoHttpRequest.java │ ├── NetworkUtils.java │ ├── OnResponseEvent.java │ └── CancelableTask.java │ ├── listener │ ├── ABExecuteCallBack.java │ └── OnViewPagerChangeSimpleListener.java │ ├── support │ ├── recyclerview │ │ ├── adapter │ │ │ ├── ABRecyclerViewAdapter.java │ │ │ ├── extra │ │ │ │ ├── ABRecyclerViewTypeExtraHolder.java │ │ │ │ └── ABRecyclerViewTypeExtraRender.java │ │ │ ├── ABRecyclerViewTypeAdapter.java │ │ │ └── ABRecyclerViewHolder.java │ │ ├── listener │ │ │ ├── OnRecyclerViewScrollLocationListener.java │ │ │ └── OnRecyclerViewScrollListener.java │ │ └── layoutmanager │ │ │ ├── ABaseLinearLayoutManager.java │ │ │ ├── ABaseGridLayoutManager.java │ │ │ └── ABaseStaggeredGridLayoutManager.java │ └── cardview │ │ ├── CardViewDelegate.java │ │ ├── CardViewImpl.java │ │ ├── CardViewJellybeanMr1.java │ │ ├── CardShadow.java │ │ ├── CardViewEclairMr1.java │ │ └── CardView.java │ ├── present │ ├── ABActivityCommon.java │ ├── ABFragment.java │ └── ABSupportFragment.java │ ├── adapter │ ├── listener │ │ ├── OnAdapterScrollListener.java │ │ ├── OnAdapterScrollSampleListener.java │ │ ├── OnConvertViewClickListener.java │ │ ├── OnAdapterClickListener.java │ │ ├── OnConvertViewLongClickListener.java │ │ └── OnAdapterLongClickListener.java │ ├── typeadapter │ │ ├── AdapterTypeRender.java │ │ ├── ABAdapterTypeRender.java │ │ ├── expand │ │ │ ├── ExpandGroupAdapterTypeRender.java │ │ │ ├── ExpandChildAdapterTypeRender.java │ │ │ └── BaseExpandTypeAdapter.java │ │ └── BaseTypeAdapter.java │ ├── ABaseHolderAdapter.java │ ├── ABaseAdapter.java │ └── ABaseExpandableListAdapter.java │ ├── utils │ ├── ABRegUtil.java │ ├── ABThreadUtil.java │ ├── Constants.java │ ├── ABColorUtil.java │ ├── ABAnimUtil.java │ ├── ABPrefsUtil.java │ └── ABJsonUtil.java │ ├── manager │ ├── OnActivityLifeCycleListener.java │ ├── OnActivityLifeCycleFullListener.java │ └── BaseActivityManager.java │ ├── system │ ├── SimulateEvents.java │ ├── ABPhone.java │ ├── WakeLocker.java │ └── appinfo │ │ └── ABAppInfo.java │ ├── objs │ └── DelayObj.java │ ├── log │ └── LogConfig.java │ ├── security │ ├── MD5.java │ └── des3 │ │ ├── Des3.java │ │ └── Base64.java │ ├── watcher │ └── OnTextCleanWatcher.java │ ├── thread │ └── ThreadPool.java │ └── application │ ├── ABApplication.java │ └── HttpApplicationController.java ├── res ├── anim │ ├── fade_in.xml │ ├── slide_bottom_in.xml │ ├── slide_left_in.xml │ ├── slide_left_out.xml │ ├── slide_right_in.xml │ ├── slide_right_out.xml │ ├── slide_top_out.xml │ ├── push_down_out.xml │ ├── push_up_in.xml │ ├── push_down_in.xml │ └── push_up_out.xml ├── values │ ├── strings.xml │ ├── dimens.xml │ ├── ids.xml │ ├── colors.xml │ ├── attrs.xml │ └── styles.xml ├── drawable │ ├── selector_bg_sheet_item.xml │ ├── selector_bg_sheet_corner_all.xml │ ├── ab__shape_corners_black.xml │ ├── shape_corners_gray_corner_all.xml │ ├── shape_corners_white_corner_all.xml │ └── shape_corners_white_corner_top_lr.xml └── layout │ ├── ab_sheet_item.xml │ ├── ab_drop_menu_item.xml │ ├── ab_drop_menu.xml │ ├── ab_horizontial_edit_menu.xml │ └── ab_sheet.xml ├── .gitignore ├── project.properties ├── proguard-project.txt ├── ant.properties └── README.md /libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjiegulu/AndroidBucket/HEAD/libs/android-support-v4.jar -------------------------------------------------------------------------------- /libs/android-support-v7-appcompat.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjiegulu/AndroidBucket/HEAD/libs/android-support-v7-appcompat.jar -------------------------------------------------------------------------------- /libs/android-support-v7-recyclerview.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangjiegulu/AndroidBucket/HEAD/libs/android-support-v7-recyclerview.jar -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/sublayout/ISubLayout.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.sublayout; 2 | 3 | /** 4 | * Created by wangjie on 14-5-4. 5 | */ 6 | public interface ISubLayout { 7 | } 8 | -------------------------------------------------------------------------------- /res/anim/fade_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | TAG_FRAGMENT_TAB_CLICK_ONLY 7 | 8 | 9 | -------------------------------------------------------------------------------- /res/anim/slide_bottom_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /res/anim/slide_left_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /res/anim/slide_left_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /res/anim/slide_right_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /res/anim/slide_right_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /res/anim/slide_top_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/core/collecion/KeySort.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.core.collecion; 2 | /*** 3 | * 分类接口,根据V value返回K key 4 | * 5 | * @param 6 | * @param 7 | */ 8 | public interface KeySort { 9 | public K getKey(V v); 10 | } 11 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/mvp/ABNonePresenterImpl.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.mvp; 2 | 3 | /** 4 | * Author: wangjie 5 | * Email: tiantian.china.2@gmail.com 6 | * Date: 2/3/15. 7 | */ 8 | public class ABNonePresenterImpl extends ABBasePresenter{ 9 | } 10 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/BaseAccessResponse.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services; 2 | 3 | /** 4 | * @author Hubert He 5 | * @version V1.0 6 | * @Description 服务访问返回值基类 7 | * @Createdate 14-9-4 10:35 8 | */ 9 | public class BaseAccessResponse { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/listener/ABExecuteCallBack.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.listener; 2 | 3 | /** 4 | * Author: wangjie 5 | * Email: tiantian.china.2@gmail.com 6 | * Date: 11/19/14. 7 | */ 8 | public interface ABExecuteCallBack { 9 | void execute(T obj); 10 | } 11 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/mvp/ABInteractor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.mvp; 2 | 3 | /** 4 | * Author: wangjie 5 | * Email: tiantian.china.2@gmail.com 6 | * Date: 7/18/14. 7 | * 8 | * MVP的Model层,主要是通向主领域层或者逻辑层的通道,由Presenter调用 9 | */ 10 | public interface ABInteractor { 11 | } 12 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/http/ABHttpMethod.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network.http; 2 | 3 | /** 4 | * @author Hubert He 5 | * @version V1.0 6 | * @Description 7 | * @Createdate 14-9-4 10:10 8 | */ 9 | public enum ABHttpMethod { 10 | GET, POST, DELETE 11 | }; 12 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/NetworkUtils.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services; 2 | 3 | /** 4 | * @author Hubert He 5 | * @version V1.0 6 | * @Description 7 | * @Createdate 15/4/9 15:13 8 | */ 9 | public class NetworkUtils { 10 | 11 | public static boolean IS_HOST_REACHABLE = true; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/mvp/ABNoneInteractorImpl.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.mvp; 2 | 3 | /** 4 | * 默认的interactor,在注入时,如果不需要注入interactor,则使用此默认Interactor 5 | * Author: wangjie 6 | * Email: tiantian.china.2@gmail.com 7 | * Date: 9/11/14. 8 | */ 9 | public class ABNoneInteractorImpl implements ABInteractor{ 10 | } 11 | -------------------------------------------------------------------------------- /res/drawable/selector_bg_sheet_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/mvp/TaskController.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.mvp; 2 | 3 | /** 4 | * @author Hubert He 5 | * @version V1.0 6 | * @Description 7 | * @Createdate 15/1/28 12:29 8 | */ 9 | public interface TaskController { 10 | 11 | void registerPresenter(ABBasePresenter presenter); 12 | 13 | void closeAllTask(); 14 | } 15 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/core/collecion/LanguageComparator_EN.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.core.collecion; 2 | 3 | import java.util.Comparator; 4 | 5 | public class LanguageComparator_EN implements Comparator { 6 | 7 | public int compare(String ostr1, String ostr2) { 8 | return ostr1.compareToIgnoreCase(ostr2); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/horizontialmenu/OnHoriMenuItemListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.horizontialmenu; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Created by wangjie on 14-5-5. 7 | */ 8 | public interface OnHoriMenuItemListener{ 9 | 10 | public abstract void onItemClick(View view, int position); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /res/drawable/selector_bg_sheet_corner_all.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/OnResponseEvent.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services; 2 | 3 | /** 4 | * @author Hubert He 5 | * @version V1.0 6 | * @Description 7 | * @Createdate 14-9-4 10:50 8 | */ 9 | public interface OnResponseEvent { 10 | /** 11 | * 线程返回回调 12 | */ 13 | T onResponse(Object object); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/exception/ServerError.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network.exception; 2 | 3 | /** 4 | * @author Hubert He 5 | * @version V1.0 6 | * @Description 7 | * @Createdate 14-9-24 21:48 8 | */ 9 | public class ServerError extends HippoException { 10 | public ServerError(String detailMessage) { 11 | super(detailMessage); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/recyclerview/adapter/ABRecyclerViewAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.recyclerview.adapter; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | 5 | /** 6 | * Author: wangjie 7 | * Email: tiantian.china.2@gmail.com 8 | * Date: 1/19/15. 9 | */ 10 | public abstract class ABRecyclerViewAdapter extends RecyclerView.Adapter { 11 | } 12 | -------------------------------------------------------------------------------- /res/layout/ab_sheet_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/core/collecion/PinyinKeySortable.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.core.collecion; 2 | 3 | /** 4 | * 拼音排序的javabean必须实现该接口 5 | * Created with IntelliJ IDEA. 6 | * Author: wangjie email:wangjie@cyyun.com 7 | * Date: 13-12-9 8 | * Time: 下午4:43 9 | */ 10 | public interface PinyinKeySortable { 11 | /** 12 | * 实现该方法,并返回要拼音排序的字母 13 | * @return 14 | */ 15 | public String getPendKey(); 16 | } 17 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/present/ABActivityCommon.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.present; 2 | 3 | import com.wangjie.androidbucket.manager.BaseActivityManager; 4 | 5 | /** 6 | * Author: wangjie 7 | * Email: tiantian.china.2@gmail.com 8 | * Date: 1/21/15. 9 | */ 10 | public interface ABActivityCommon { 11 | BaseActivityManager getBaseActivityManager(); 12 | 13 | void setBaseActivityManager(BaseActivityManager baseActivityManager); 14 | } 15 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/Network.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network; 2 | 3 | import com.wangjie.androidbucket.services.network.exception.HippoException; 4 | 5 | /** 6 | * @author Hubert He 7 | * @version V1.0 8 | * @Description 9 | * @Createdate 14-9-25 11:48 10 | */ 11 | public interface Network> { 12 | public NetworkResponse performRequest(T hippoRequest) throws HippoException; 13 | } 14 | -------------------------------------------------------------------------------- /res/drawable/ab__shape_corners_black.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/listener/OnAdapterScrollListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter.listener; 2 | 3 | import android.widget.AbsListView; 4 | 5 | /** 6 | * Author: wangjie 7 | * Email: tiantian.china.2@gmail.com 8 | * Date: 12/3/14. 9 | */ 10 | public interface OnAdapterScrollListener extends AbsListView.OnScrollListener { 11 | void onTopWhenScrollIdle(AbsListView view); 12 | 13 | void onBottomWhenScrollIdle(AbsListView view); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /res/drawable/shape_corners_gray_corner_all.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /res/drawable/shape_corners_white_corner_all.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /res/drawable/shape_corners_white_corner_top_lr.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/CancelableTask.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services; 2 | 3 | import java.util.Collection; 4 | 5 | /** 6 | * @author Hubert He 7 | * @version V1.0 8 | * @Description 可撤销任务接口 9 | * @Createdate 14-9-3 15:53 10 | */ 11 | public interface CancelableTask { 12 | 13 | public void addListener(Collection cancelableTaskCollection); 14 | 15 | public boolean cancel(boolean mayInterruptIfRunning); 16 | 17 | public void remove(); 18 | } 19 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/RequestListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network; 2 | 3 | /** 4 | * Callback interface for delivering parsed responses. 5 | */ 6 | public abstract class RequestListener { 7 | 8 | public void onPreExecute() { 9 | } 10 | 11 | public void onResponseInBackground(T response) { 12 | } 13 | 14 | /** 15 | * Called when a response is received. 16 | */ 17 | public abstract void onResponse(T response); 18 | } 19 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/borderscrollview/OnScrollChangedListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.borderscrollview; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * Author: wangjie email:tiantian.china.2@gmail.com 6 | * Date: 13-9-6 7 | * Time: 下午2:53 8 | */ 9 | public interface OnScrollChangedListener { 10 | public void onScrollChanged(int l, int t, int oldl, int oldt); 11 | 12 | public void onScrollTop(); 13 | 14 | public void onScrollBottom(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/utils/ABRegUtil.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.utils; 2 | 3 | /** 4 | * Author: wangjie 5 | * Email: tiantian.china.2@gmail.com 6 | * Date: 8/1/14. 7 | */ 8 | public class ABRegUtil { 9 | 10 | /** 11 | * 手机号码正则 12 | */ 13 | public static final String REG_PHONE_CHINA = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$"; 14 | 15 | /** 16 | * 邮箱正则 17 | */ 18 | public static final String REG_EMAIL = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*"; 19 | 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /res/layout/ab_drop_menu_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/recyclerview/listener/OnRecyclerViewScrollLocationListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.recyclerview.listener; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | 5 | /** 6 | * 特殊的滚动监听,可以监听滚动到顶部还是底部 7 | * Author: wangjie 8 | * Email: tiantian.china.2@gmail.com 9 | * Date: 1/22/15. 10 | */ 11 | public interface OnRecyclerViewScrollLocationListener { 12 | void onTopWhenScrollIdle(RecyclerView recyclerView); 13 | 14 | void onBottomWhenScrollIdle(RecyclerView recyclerView); 15 | } 16 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/exception/RetryFailedException.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network.exception; 2 | 3 | /** 4 | * @author Hubert He 5 | * @version V1.0 6 | * @Description 7 | * @Createdate 15/1/9 13:41 8 | */ 9 | public class RetryFailedException extends HippoException { 10 | 11 | public RetryFailedException(String detailMessage) { 12 | super(detailMessage); 13 | } 14 | 15 | public RetryFailedException(String detailMessage, Exception e) { 16 | super(detailMessage, e); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/manager/OnActivityLifeCycleListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.manager; 2 | 3 | import android.os.Bundle; 4 | 5 | /** 6 | * Author: wangjie 7 | * Email: tiantian.china.2@gmail.com 8 | * Date: 8/11/14. 9 | */ 10 | public interface OnActivityLifeCycleListener { 11 | @Deprecated 12 | public void onActivityCreateCallback(Bundle savedInstanceState); 13 | 14 | public void onActivityResumeCallback(); 15 | 16 | public void onActivityPauseCallback(); 17 | 18 | public void onActivityDestroyCallback(); 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # files for the dex VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # generated files 12 | bin/ 13 | gen/ 14 | 15 | # Local configuration file (sdk path, etc) 16 | local.properties 17 | 18 | # Eclipse project files 19 | .classpath 20 | .project 21 | 22 | # Proguard folder generated by Eclipse 23 | proguard/ 24 | 25 | # Intellij project files 26 | *.iml 27 | *.ipr 28 | *.iws 29 | .idea/ 30 | 31 | # User define 32 | out/ 33 | proguard_logs/* 34 | 35 | build/ 36 | .gradle/ 37 | 38 | local.properties 39 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/interceptor/Interceptor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network.interceptor; 2 | 3 | import com.wangjie.androidbucket.services.network.HippoRequest; 4 | import com.wangjie.androidbucket.services.network.exception.HippoException; 5 | 6 | /** 7 | * @author Hubert He 8 | * @version V1.0 9 | * @Description 10 | * @Createdate 14-9-24 18:08 11 | */ 12 | public interface Interceptor { 13 | 14 | boolean getInterruptRule(T request); 15 | 16 | void dispatch(T request) throws HippoException; 17 | } 18 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/utils/ABThreadUtil.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.utils; 2 | 3 | import com.wangjie.androidbucket.log.Logger; 4 | 5 | /** 6 | * Author: wangjie 7 | * Email: tiantian.china.2@gmail.com 8 | * Date: 7/21/14. 9 | */ 10 | public class ABThreadUtil { 11 | public static final String TAG = ABThreadUtil.class.getSimpleName(); 12 | 13 | public static void sleep(long millis) { 14 | try { 15 | Thread.sleep(millis); 16 | } catch (InterruptedException e) { 17 | Logger.e(TAG, e); 18 | } 19 | } 20 | 21 | 22 | } -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/recyclerview/listener/OnRecyclerViewScrollListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.recyclerview.listener; 2 | 3 | /** 4 | * 普通的滚动监听,可以在LayoutManager中获取到RecyclerViewScrollManager后add多个 5 | * Author: wangjie 6 | * Email: tiantian.china.2@gmail.com 7 | * Date: 1/22/15. 8 | */ 9 | public interface OnRecyclerViewScrollListener { 10 | public void onScrollStateChanged(android.support.v7.widget.RecyclerView recyclerView, int newState); 11 | 12 | public void onScrolled(android.support.v7.widget.RecyclerView recyclerView, int dx, int dy); 13 | } 14 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/listener/OnViewPagerChangeSimpleListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.listener; 2 | 3 | import android.support.v4.view.ViewPager; 4 | 5 | /** 6 | * Author: wangjie 7 | * Email: tiantian.china.2@gmail.com 8 | * Date: 9/2/14. 9 | */ 10 | public class OnViewPagerChangeSimpleListener implements ViewPager.OnPageChangeListener { 11 | @Override 12 | public void onPageScrolled(int i, float v, int i2) {} 13 | 14 | @Override 15 | public void onPageSelected(int i) {} 16 | 17 | @Override 18 | public void onPageScrollStateChanged(int i) {} 19 | } 20 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/cardview/CardViewDelegate.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.cardview; 2 | 3 | /** 4 | * Author: wangjie 5 | * Email: tiantian.china.2@gmail.com 6 | * Date: 12/15/14. 7 | */ 8 | 9 | import android.graphics.drawable.Drawable; 10 | 11 | /** 12 | * Interface provided by CardView to implementations. 13 | *

14 | * Necessary to resolve circular dependency between base CardView and platform implementations. 15 | */ 16 | interface CardViewDelegate { 17 | 18 | void setBackgroundDrawable(Drawable paramDrawable); 19 | 20 | Drawable getBackground(); 21 | } 22 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/borderscrollview/OnScrollChangedListenerSimple.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.borderscrollview; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * Author: wangjie email:tiantian.china.2@gmail.com 6 | * Date: 13-9-9 7 | * Time: 下午2:39 8 | */ 9 | public class OnScrollChangedListenerSimple implements OnScrollChangedListener{ 10 | @Override 11 | public void onScrollChanged(int l, int t, int oldl, int oldt) { 12 | } 13 | 14 | @Override 15 | public void onScrollTop() { 16 | } 17 | 18 | @Override 19 | public void onScrollBottom() { 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | android.library=true 14 | # Project target. 15 | target=android-21 -------------------------------------------------------------------------------- /res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 1dp 9 | 10 | 2dp 11 | 12 | 2dp 13 | 15 | 1dp 16 | 17 | -------------------------------------------------------------------------------- /res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/http/interceptor/HttpMethodInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network.http.interceptor; 2 | 3 | import com.wangjie.androidbucket.services.network.http.HttpAccessParameter; 4 | 5 | /** 6 | * Author: wangjie 7 | * Email: tiantian.china.2@gmail.com 8 | * Date: 9/18/14. 9 | */ 10 | public interface HttpMethodInterceptor { 11 | 12 | Object interceptGet(HttpAccessParameter accessParameter) throws Exception; 13 | Object interceptPost(HttpAccessParameter accessParameter) throws Exception; 14 | Object interceptDelete(HttpAccessParameter accessParameter) throws Exception; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/system/SimulateEvents.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.system; 2 | 3 | import android.view.KeyEvent; 4 | import android.widget.EditText; 5 | 6 | /** 7 | * Created by wangjie on 6/12/14. 8 | */ 9 | public class SimulateEvents { 10 | 11 | /** 12 | * 模拟输入框删除 13 | * @param et 14 | */ 15 | public static void editTextDel(EditText et){ 16 | // 动作按下 17 | int action = KeyEvent.ACTION_DOWN; 18 | // code:删除,其他code也可以 19 | int code = KeyEvent.KEYCODE_DEL; 20 | KeyEvent event = new KeyEvent(action, code); 21 | et.onKeyDown(KeyEvent.KEYCODE_DEL, event); 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/manager/OnActivityLifeCycleFullListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.manager; 2 | 3 | import android.os.Bundle; 4 | 5 | /** 6 | * Author: wangjie 7 | * Email: tiantian.china.2@gmail.com 8 | * Date: 8/11/14. 9 | */ 10 | public interface OnActivityLifeCycleFullListener extends OnActivityLifeCycleListener { 11 | public void onActivityStartCallBack(); 12 | 13 | public void onActivityRestartCallBack(); 14 | 15 | public void onActivityStopCallBack(); 16 | 17 | public void onActivitySaveInstanceStateCallBack(Bundle outState); 18 | 19 | public void onActivityRestoreInstanceStateCallBack(Bundle savedInstanceState); 20 | } 21 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/cardview/CardViewImpl.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.cardview; 2 | 3 | /** 4 | * Author: wangjie 5 | * Email: tiantian.china.2@gmail.com 6 | * Date: 12/15/14. 7 | */ 8 | 9 | import android.content.Context; 10 | 11 | /** 12 | * Interface for platform specific CardView implementations. 13 | */ 14 | interface CardViewImpl { 15 | 16 | void initialize(CardViewDelegate cardView, Context context, int backgroundColor, float radius, CardShadow cardShadow); 17 | 18 | void setRadius(CardViewDelegate cardView, float radius); 19 | 20 | float getRadius(CardViewDelegate cardView); 21 | 22 | void initStatic(); 23 | } 24 | -------------------------------------------------------------------------------- /res/layout/ab_drop_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 17 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/typeadapter/AdapterTypeRender.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter.typeadapter; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * 用于对不同类型item数据到UI的渲染 7 | * Author: wangjie 8 | * Email: tiantian.china.2@gmail.com 9 | * Date: 9/14/14. 10 | */ 11 | public interface AdapterTypeRender { 12 | 13 | /** 14 | * 返回一个item的convertView,也就是BaseAdapter中getView方法中返回的convertView 15 | * @return 16 | */ 17 | View getConvertView(); 18 | 19 | /** 20 | * 填充item中各个控件的事件,比如按钮点击事件等 21 | */ 22 | void fitEvents(); 23 | 24 | /** 25 | * 对指定position的item进行数据的适配 26 | * @param position 27 | */ 28 | void fitDatas(int position); 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/utils/Constants.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.utils; 2 | 3 | /** 4 | * Created by zoe on 15/1/6. 5 | */ 6 | public class Constants { 7 | /** 8 | * Unknown network class 9 | */ 10 | public static final int NETWORK_CLASS_UNKNOWN = 0; 11 | 12 | /** 13 | * wifi net work 14 | */ 15 | public static final int NETWORK_WIFI = 1; 16 | 17 | /** 18 | * "2G" networks 19 | */ 20 | public static final int NETWORK_CLASS_2_G = 2; 21 | 22 | /** 23 | * "3G" networks 24 | */ 25 | public static final int NETWORK_CLASS_3_G = 3; 26 | 27 | /** 28 | * "4G" networks 29 | */ 30 | public static final int NETWORK_CLASS_4_G = 4; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/typeadapter/ABAdapterTypeRender.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter.typeadapter; 2 | 3 | /** 4 | * 用于对不同类型item数据到UI的渲染 5 | * Author: wangjie 6 | * Email: tiantian.china.2@gmail.com 7 | * Date: 9/14/14. 8 | */ 9 | public interface ABAdapterTypeRender { 10 | 11 | /** 12 | * 返回一个item的可复用de组件,可以是BaseAdapter中getView方法中返回的convertView,也可以是RecyclerView的ViewHolder 13 | * 14 | * @return 15 | */ 16 | T getReusableComponent(); 17 | 18 | /** 19 | * 填充item中各个控件的事件,比如按钮点击事件等 20 | */ 21 | void fitEvents(); 22 | 23 | /** 24 | * 对指定position的item进行数据的适配 25 | * 26 | * @param position 27 | */ 28 | void fitDatas(int position); 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/mvp/ABBaseTaskManager.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.mvp; 2 | 3 | import com.wangjie.androidbucket.services.CancelableTask; 4 | 5 | /** 6 | * @author Hubert He 7 | * @version V1.0 8 | * @Description 业务处理基类 9 | * @Createdate 14-9-3 17:16 10 | */ 11 | public interface ABBaseTaskManager { 12 | 13 | /** 14 | * 添加可cancel任务 15 | * 16 | * @param cancelableTask 17 | */ 18 | void addCancelableTask(CancelableTask cancelableTask); 19 | 20 | /** 21 | * 移除可cancel任务(task完成后调用此方法) 22 | * 23 | * @param cancelableTask 24 | */ 25 | void removeCancelableTask(CancelableTask cancelableTask); 26 | 27 | /** 28 | * 关闭所有任务 29 | */ 30 | void closeAllTask(); 31 | } 32 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/DispatchRequestListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network; 2 | 3 | /** 4 | * @author Hubert He 5 | * @version V1.0 6 | * @Description 7 | * @Createdate 15/4/9 11:44 8 | */ 9 | public abstract class DispatchRequestListener extends RequestListener

{ 10 | 11 | private R result; 12 | 13 | @Override 14 | public final void onResponseInBackground(P response) { 15 | result = onRunInBackground(response); 16 | } 17 | 18 | public abstract R onRunInBackground(P response); 19 | 20 | public abstract void onResponseParsed(R result); 21 | 22 | @Override 23 | public final void onResponse(P response) { 24 | onResponseParsed(result); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/dropdownmenu/IDropMenu.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.dropdownmenu; 2 | 3 | import android.view.View; 4 | import android.widget.AdapterView; 5 | 6 | /** 7 | * Created with IntelliJ IDEA. 8 | * Author: wangjie email:tiantian.china.2@gmail.com 9 | * Date: 13-11-27 10 | * Time: 下午4:44 11 | */ 12 | public interface IDropMenu { 13 | /** 14 | * 设置下拉菜单的每一项名称 15 | * @return 16 | */ 17 | public String[] getDropDownMenuItems(); 18 | 19 | /** 20 | * 下拉菜单item点击回调方法 21 | * @param parent 22 | * @param view 23 | * @param position 24 | * @param id 25 | */ 26 | public void onDropDownMenuItemClick(AdapterView parent, View view, int position, long id); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/listener/OnAdapterScrollSampleListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter.listener; 2 | 3 | import android.widget.AbsListView; 4 | 5 | /** 6 | * Author: wangjie 7 | * Email: tiantian.china.2@gmail.com 8 | * Date: 12/3/14. 9 | */ 10 | public class OnAdapterScrollSampleListener implements OnAdapterScrollListener{ 11 | @Override 12 | public void onScrollStateChanged(AbsListView view, int scrollState) {} 13 | 14 | @Override 15 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {} 16 | 17 | @Override 18 | public void onTopWhenScrollIdle(AbsListView view) {} 19 | 20 | @Override 21 | public void onBottomWhenScrollIdle(AbsListView view) {} 22 | } 23 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/exception/HippoException.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network.exception; 2 | 3 | /** 4 | * @author Hubert He 5 | * @version V1.0 6 | * @Description 7 | * @Createdate 14-9-24 14:19 8 | */ 9 | public class HippoException extends Exception { 10 | 11 | private String errorMessage = null; 12 | 13 | private static final String TAG = HippoException.class.getSimpleName(); 14 | 15 | public HippoException(String detailMessage) { 16 | super(TAG + ": " + detailMessage); 17 | errorMessage = detailMessage; 18 | } 19 | 20 | public HippoException(String detailMessage, Exception e) { 21 | super(TAG + ": " + detailMessage, e); 22 | errorMessage = detailMessage; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/typeadapter/expand/ExpandGroupAdapterTypeRender.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter.typeadapter.expand; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * 用于对不同类型item的group数据到UI的渲染 7 | * Author: wangjie 8 | * Email: tiantian.china.2@gmail.com 9 | * Date: 9/14/14. 10 | */ 11 | public interface ExpandGroupAdapterTypeRender { 12 | 13 | /** 14 | * 返回一个item的convertView,也就是BaseAdapter中getView方法中返回的convertView 15 | * 16 | * @return 17 | */ 18 | View getConvertView(); 19 | 20 | /** 21 | * 填充item中各个控件的事件,比如按钮点击事件等 22 | */ 23 | void fitEvents(); 24 | 25 | /** 26 | * 对指定position的item进行数据的适配 27 | * 28 | * @param groupPosition 29 | */ 30 | void fitDatas(int groupPosition); 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/cardview/CardViewJellybeanMr1.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.cardview; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | import android.graphics.RectF; 6 | 7 | /** 8 | * Author: wangjie 9 | * Email: tiantian.china.2@gmail.com 10 | * Date: 12/15/14. 11 | */ 12 | class CardViewJellybeanMr1 extends CardViewEclairMr1 { 13 | 14 | @Override 15 | public void initStatic() { 16 | RoundRectDrawableWithShadow.sRoundRectHelper = new RoundRectDrawableWithShadow.RoundRectHelper() { 17 | 18 | @Override 19 | public void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius, Paint paint) { 20 | canvas.drawRoundRect(bounds, cornerRadius, cornerRadius, paint); 21 | } 22 | }; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /res/layout/ab_horizontial_edit_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 10 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #f1f0f5 5 | 6 | 7 | 8 | 9 | 10 | #FFFAFAFA 11 | 12 | #FF202020 13 | 14 | #37000000 15 | 16 | 17 | #03000000 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/typeadapter/expand/ExpandChildAdapterTypeRender.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter.typeadapter.expand; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * 用于对不同类型item数据到UI的渲染 7 | * Author: wangjie 8 | * Email: tiantian.china.2@gmail.com 9 | * Date: 9/14/14. 10 | */ 11 | public interface ExpandChildAdapterTypeRender { 12 | 13 | /** 14 | * 返回一个item的convertView,也就是BaseAdapter中getView方法中返回的convertView 15 | * 16 | * @return 17 | */ 18 | View getConvertView(); 19 | 20 | /** 21 | * 填充item中各个控件的事件,比如按钮点击事件等 22 | */ 23 | void fitEvents(); 24 | 25 | /** 26 | * 对指定position的item进行数据的适配 27 | * 28 | * @param groupPosition 29 | * @param childPosition 30 | */ 31 | void fitDatas(int groupPosition, int childPosition); 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/objs/DelayObj.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.objs; 2 | 3 | /** 4 | * Created by wangjie on 14-5-4. 5 | */ 6 | public class DelayObj { 7 | private Class clazz; 8 | private T obj; 9 | 10 | public Class getClazz() { 11 | return clazz; 12 | } 13 | 14 | public DelayObj setClazz(Class clazz) { 15 | this.clazz = clazz; 16 | return this; 17 | } 18 | 19 | public T getObj() { 20 | return obj; 21 | } 22 | 23 | public DelayObj setObj(T obj) { 24 | this.obj = obj; 25 | return this; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return "DelayObj{" + 31 | "clazz=" + clazz + 32 | ", obj=" + obj + 33 | '}'; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/horizontalgallery/HorizontalGalleryBaseAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.horizontalgallery; 2 | 3 | import android.view.View; 4 | import android.widget.BaseAdapter; 5 | 6 | /** 7 | * Author: wangjie 8 | * Email: tiantian.china.2@gmail.com 9 | * Date: 11/13/14. 10 | */ 11 | public abstract class HorizontalGalleryBaseAdapter extends BaseAdapter{ 12 | 13 | /** 14 | * 传入的item(convertView)被选中了,可以在这个方法中对convertView进行修改(高亮等) 15 | * @param convertView 16 | * @param position 17 | */ 18 | public abstract void viewSelected(View convertView, int position); 19 | 20 | /** 21 | * 传入的item(convertView)未被选中了,可以在这个方法中对convertView进行修改(取消高亮等) 22 | * @param convertView 23 | * @param position 24 | */ 25 | public abstract void viewUnselected(View convertView, int position); 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /ant.properties: -------------------------------------------------------------------------------- 1 | # This file is used to override default values used by the Ant build system. 2 | # 3 | # This file must be checked into Version Control Systems, as it is 4 | # integral to the build system of your project. 5 | 6 | # This file is only used by the Ant script. 7 | 8 | # You can use this to override default values such as 9 | # 'source.dir' for the location of your java source folder and 10 | # 'out.dir' for the location of your output folder. 11 | 12 | # You can also use it define how the release builds are signed by declaring 13 | # the following properties: 14 | # 'key.store' for the location of your keystore and 15 | # 'key.alias' for the name of the key to use. 16 | # The password will be asked during the build when you use the 'release' target. 17 | 18 | 19 | sdk.dir=/Users/wangjie/work/java/android/sdk 20 | jar.libs.dir=../../xrdoctor_android/libs 21 | #jar.libs.dir=../../libs 22 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/recyclerview/adapter/extra/ABRecyclerViewTypeExtraHolder.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.recyclerview.adapter.extra; 2 | 3 | import android.view.View; 4 | import com.wangjie.androidbucket.support.recyclerview.adapter.ABRecyclerViewHolder; 5 | 6 | /** 7 | * Author: wangjie 8 | * Email: tiantian.china.2@gmail.com 9 | * Date: 1/22/15. 10 | */ 11 | public class ABRecyclerViewTypeExtraHolder extends ABRecyclerViewHolder { 12 | public ABRecyclerViewTypeExtraHolder(View itemView) { 13 | super(itemView); 14 | } 15 | 16 | /** 17 | * 保存当前position(list index,不包括headerView和footerView) 18 | */ 19 | private int realItemPosition; 20 | 21 | public int getRealItemPosition() { 22 | return realItemPosition; 23 | } 24 | 25 | protected void setRealItemPosition(int realItemPosition) { 26 | this.realItemPosition = realItemPosition; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /res/anim/push_down_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /res/anim/push_up_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/recyclerview/adapter/extra/ABRecyclerViewTypeExtraRender.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.recyclerview.adapter.extra; 2 | 3 | import android.view.View; 4 | import com.wangjie.androidbucket.adapter.typeadapter.ABAdapterTypeRender; 5 | 6 | /** 7 | * 带有header或者footer的view 8 | * Author: wangjie 9 | * Email: tiantian.china.2@gmail.com 10 | * Date: 1/22/15. 11 | */ 12 | /*public*/ class ABRecyclerViewTypeExtraRender implements ABAdapterTypeRender { 13 | protected ABRecyclerViewTypeExtraHolder holder; 14 | 15 | protected ABRecyclerViewTypeExtraRender(View extraView) { 16 | holder = new ABRecyclerViewTypeExtraHolder(extraView); 17 | } 18 | 19 | @Override 20 | public ABRecyclerViewTypeExtraHolder getReusableComponent() { 21 | return holder; 22 | } 23 | 24 | @Override 25 | public void fitEvents() { 26 | 27 | } 28 | 29 | @Override 30 | public void fitDatas(int position) { 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /res/anim/push_down_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /res/anim/push_up_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 18 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/http/HttpConstants.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network.http; 2 | 3 | /** 4 | * @author Hubert He 5 | * @version V1.0 6 | * @Description HTTP常量 7 | * @Createdate 14-9-5 11:14 8 | */ 9 | public class HttpConstants { 10 | 11 | public final static String CONTENT_TYPE_JSON = "application/json"; 12 | 13 | public final static String CONTENT_TYPE_HTML = "text/html"; 14 | 15 | public final static String CONTENT_TYPE_FILE = "application/octet-stream"; 16 | 17 | public final static String CONTENT_TYPE_MULTIPART_FORM_DATA = "multipart/form-data"; 18 | 19 | public final static String CONTENT_TYPE_XML = "text/xml"; 20 | 21 | public final static String CONTENT_TYPE_APK = "application/vnd.android.package-archive"; 22 | 23 | public final static String CONTENT_TYPE_IMAGE = "image/*"; 24 | 25 | public final static String CONTENT_TYPE_EMPTY = ""; 26 | 27 | public static class HeaderType { 28 | public final static String HTTP_REFERER_HEADER = "referer"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/cardview/CardShadow.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.cardview; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Author: wangjie 7 | * Email: tiantian.china.2@gmail.com 8 | * Date: 12/16/14. 9 | */ 10 | public class CardShadow implements Serializable{ 11 | 12 | private int shadowStartColor; 13 | private int shadowEndColor; 14 | private float shadowSize; 15 | 16 | public int getShadowStartColor() { 17 | return shadowStartColor; 18 | } 19 | 20 | public void setShadowStartColor(int shadowStartColor) { 21 | this.shadowStartColor = shadowStartColor; 22 | } 23 | 24 | public int getShadowEndColor() { 25 | return shadowEndColor; 26 | } 27 | 28 | public void setShadowEndColor(int shadowEndColor) { 29 | this.shadowEndColor = shadowEndColor; 30 | } 31 | 32 | public float getShadowSize() { 33 | return shadowSize; 34 | } 35 | 36 | public void setShadowSize(float shadowSize) { 37 | this.shadowSize = shadowSize; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/log/LogConfig.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.log; 2 | 3 | /** 4 | * 日志配置 5 | * Created with IntelliJ IDEA. 6 | * Author: wangjie email:tiantian.china.2@gmail.com 7 | * Date: 14-3-26 8 | * Time: 下午4:12 9 | */ 10 | public class LogConfig { 11 | private boolean debug = true; // 开启控制台输出模式 12 | private boolean logFile = false; // 开启客户端本地日志记录模式 13 | private String logFilePath; // 本地日志记录的路径 14 | 15 | public boolean isDebug() { 16 | return debug; 17 | } 18 | 19 | public LogConfig setDebug(boolean debug) { 20 | this.debug = debug; 21 | return this; 22 | } 23 | 24 | public boolean isLogFile() { 25 | return logFile; 26 | } 27 | 28 | public LogConfig setLogFile(boolean logFile) { 29 | this.logFile = logFile; 30 | return this; 31 | } 32 | 33 | public String getLogFilePath() { 34 | return logFilePath; 35 | } 36 | 37 | public LogConfig setLogFilePath(String logFilePath) { 38 | this.logFilePath = logFilePath; 39 | return this; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/drawable/CornerDrawable.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.drawable; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.Paint; 5 | 6 | /** 7 | * Author: wangjie 8 | * Email: tiantian.china.2@gmail.com 9 | * Date: 1/13/15. 10 | */ 11 | public class CornerDrawable extends InnerBorderDrawable { 12 | public CornerDrawable() { 13 | } 14 | public CornerDrawable(int borderColor, int fillColor, float corner, float border) { 15 | super(borderColor, fillColor, corner, border); 16 | } 17 | 18 | @Override 19 | public void draw(Canvas canvas) { 20 | // fill 21 | paint.setStyle(Paint.Style.FILL); 22 | paint.setColor(fillColor); 23 | canvas.drawRoundRect(drawArea, corner, corner, paint); 24 | 25 | if (border > 0) { 26 | // border 27 | paint.setStyle(Paint.Style.STROKE); 28 | paint.setColor(borderColor); 29 | paint.setStrokeWidth(border); 30 | canvas.drawRoundRect(drawArea, corner, corner, paint); 31 | } 32 | 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/listener/OnConvertViewClickListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter.listener; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | import android.view.View; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by wangjie on 6/24/14. 11 | */ 12 | public abstract class OnConvertViewClickListener implements View.OnClickListener{ 13 | 14 | private View convertView; 15 | private int[] positionIds; 16 | public OnConvertViewClickListener(View convertView, int... positionIds) { 17 | this.convertView = convertView; 18 | this.positionIds = positionIds; 19 | } 20 | 21 | @TargetApi(Build.VERSION_CODES.DONUT) 22 | @Override 23 | public void onClick(View v) { 24 | int len = positionIds.length; 25 | int[] positions = new int[len]; 26 | for(int i = 0; i < len; i++){ 27 | positions[i] = (int) convertView.getTag(positionIds[i]); 28 | } 29 | onClickCallBack(v, positions); 30 | } 31 | 32 | public abstract void onClickCallBack(View registedView, int... positionIds); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/mvp/ABActivityViewer.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.mvp; 2 | 3 | /** 4 | * Author: wangjie 5 | * Email: tiantian.china.2@gmail.com 6 | * Date: 7/17/14. 7 | *

8 | * MVP的View层,UI相关,Activity需要实现该interface 9 | * 它会包含一个Presenter的引用,当有事件发生(比如按钮点击后),会调用Presenter层的方法 10 | */ 11 | public interface ABActivityViewer extends TaskController{ 12 | 13 | /** 14 | * 显示Toast信息 15 | * 16 | * @param message 17 | */ 18 | void showToastMessage(String message); 19 | 20 | /** 21 | * 显示Info信息 22 | * 23 | * @param message 24 | */ 25 | void showInfoDialog(String message); 26 | 27 | /** 28 | * 显示Info信息 29 | * 30 | * @param message 31 | */ 32 | void showInfoDialog(String title, String message); 33 | 34 | /** 35 | * 显示正在加载对话框 36 | * @param message 37 | */ 38 | void showLoadingDialog(String message); 39 | 40 | /** 41 | * 取消加载对话框 42 | */ 43 | void cancelLoadingDialog(); 44 | 45 | /** 46 | * 显示信息对话框 47 | */ 48 | void showInfoDialog(String title, String message, String okButtonText); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/listener/OnAdapterClickListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter.listener; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | import android.view.View; 6 | import com.wangjie.androidbucket.R; 7 | 8 | /** 9 | * 已经弃用,推荐使用OnConvertViewClickListener 10 | * Created by wangjie on 6/24/14. 11 | */ 12 | @Deprecated 13 | public abstract class OnAdapterClickListener implements View.OnClickListener{ 14 | 15 | private View convertView; 16 | private int[] positionIds; 17 | public OnAdapterClickListener(View convertView, int... positionIds) { 18 | this.convertView = convertView; 19 | this.positionIds = positionIds; 20 | } 21 | 22 | @TargetApi(Build.VERSION_CODES.DONUT) 23 | @Override 24 | public void onClick(View v) { 25 | int len = positionIds.length; 26 | int[] positions = new int[len]; 27 | for(int i = 0; i < len; i++){ 28 | positions[i] = (int) convertView.getTag(positionIds[i]); 29 | } 30 | onClickCallBack(positions); 31 | } 32 | 33 | public abstract void onClickCallBack(int... positionIds); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/listener/OnConvertViewLongClickListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter.listener; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | import android.view.View; 6 | 7 | /** 8 | * Author: wangjie 9 | * Email: tiantian.china.2@gmail.com 10 | * Date: 9/2/14. 11 | */ 12 | public abstract class OnConvertViewLongClickListener implements View.OnLongClickListener { 13 | private View convertView; 14 | private int[] positionIds; 15 | 16 | public OnConvertViewLongClickListener(View convertView, int... positionIds) { 17 | this.convertView = convertView; 18 | this.positionIds = positionIds; 19 | } 20 | 21 | @TargetApi(Build.VERSION_CODES.DONUT) 22 | @Override 23 | public boolean onLongClick(View v) { 24 | int len = positionIds.length; 25 | int[] positions = new int[len]; 26 | for (int i = 0; i < len; i++) { 27 | positions[i] = (int) convertView.getTag(positionIds[i]); 28 | } 29 | return onLongClickCallBack(v, positions); 30 | } 31 | 32 | public abstract boolean onLongClickCallBack(View registedView, int... positionIds); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/utils/ABColorUtil.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.utils; 2 | 3 | import android.graphics.Color; 4 | 5 | /** 6 | * Author: wangjie 7 | * Email: tiantian.china.2@gmail.com 8 | * Date: 1/18/15. 9 | */ 10 | public class ABColorUtil { 11 | /** 12 | * 颜色加深处理 13 | * from: http://blog.csdn.net/jdsjlzx/article/details/41441083 14 | * @param RGBValues RGB的值,由alpha(透明度)、red(红)、green(绿)、blue(蓝)构成, 15 | * Android中我们一般使用它的16进制, 16 | * 例如:"#FFAABBCC",最左边到最右每两个字母就是代表alpha(透明度)、 17 | * red(红)、green(绿)、blue(蓝)。每种颜色值占一个字节(8位),值域0~255 18 | * 所以下面使用移位的方法可以得到每种颜色的值,然后每种颜色值减小一下,在合成RGB颜色,颜色就会看起来深一些了 19 | * @return 20 | */ 21 | public static int colorBurn(int RGBValues) { 22 | int alpha = RGBValues >> 24; 23 | int red = RGBValues >> 16 & 0xFF; 24 | int green = RGBValues >> 8 & 0xFF; 25 | int blue = RGBValues & 0xFF; 26 | red = (int) Math.floor(red * (1 - 0.1)); 27 | green = (int) Math.floor(green * (1 - 0.1)); 28 | blue = (int) Math.floor(blue * (1 - 0.1)); 29 | return Color.rgb(red, green, blue); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/utils/ABAnimUtil.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.utils; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * Author: wangjie 7 | * Email: tiantian.china.2@gmail.com 8 | * Date: 8/4/14. 9 | */ 10 | public class ABAnimUtil { 11 | private static Random random; 12 | 13 | /** 14 | * 生成一个振动频率 15 | * @param count 16 | * @param scope 17 | * @return 18 | */ 19 | public static float[] generateShakeRate(int count, int scope){ 20 | if(scope < 0){ 21 | scope = -scope; 22 | } 23 | if(scope == 0){ 24 | scope = 10; 25 | } 26 | if(null == random){ 27 | random = new Random(); 28 | } 29 | 30 | float[] rate = new float[count]; 31 | for(int i = 0; i < count; i++){ 32 | if(i == 0 || i == count - 1){ // 头尾都为0 33 | rate[i] = 0; 34 | continue; 35 | } 36 | if(i % 2 == 0){ 37 | rate[i] = random.nextInt(scope); 38 | }else{ 39 | rate[i] = random.nextInt(scope) - scope; 40 | } 41 | } 42 | return rate; 43 | } 44 | 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/listener/OnAdapterLongClickListener.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter.listener; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | import android.view.View; 6 | 7 | /** 8 | * 已经弃用,推荐使用OnConvertViewLongClickListener 9 | * Author: wangjie 10 | * Email: tiantian.china.2@gmail.com 11 | * Date: 9/2/14. 12 | */ 13 | @Deprecated 14 | public abstract class OnAdapterLongClickListener implements View.OnLongClickListener{ 15 | private View convertView; 16 | private int[] positionIds; 17 | public OnAdapterLongClickListener(View convertView, int... positionIds) { 18 | this.convertView = convertView; 19 | this.positionIds = positionIds; 20 | } 21 | 22 | @TargetApi(Build.VERSION_CODES.DONUT) 23 | @Override 24 | public boolean onLongClick(View v) { 25 | int len = positionIds.length; 26 | int[] positions = new int[len]; 27 | for(int i = 0; i < len; i++){ 28 | positions[i] = (int) convertView.getTag(positionIds[i]); 29 | } 30 | onLongClickCallBack(positions); 31 | return true; 32 | } 33 | 34 | public abstract void onLongClickCallBack(int... positionIds); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/RetryPolicy.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network; 2 | 3 | import com.wangjie.androidbucket.services.network.exception.HippoException; 4 | import com.wangjie.androidbucket.services.network.exception.RetryFailedException; 5 | 6 | /** 7 | * @author Hubert He 8 | * @version V1.0 9 | * @Description 10 | * @Createdate 15/2/2 10:59 11 | */ 12 | public class RetryPolicy { 13 | 14 | private static final int DEFAULT_RETRY_COUNT = 3; 15 | 16 | public RetryPolicy() { 17 | this(DEFAULT_RETRY_COUNT); 18 | } 19 | 20 | public RetryPolicy(int currentCount) { 21 | this.currentCount = currentCount; 22 | } 23 | 24 | private int currentCount; 25 | 26 | public int getCurrentCount() { 27 | return currentCount; 28 | } 29 | 30 | public void retry(HippoException e) throws RetryFailedException { 31 | if (currentCount <= 0) { 32 | throw new RetryFailedException("Retry request failed.", e); 33 | } 34 | currentCount--; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "RetryPolicy{" + 40 | "currentCount=" + currentCount + 41 | '}'; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/NestedGridView.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.GridView; 6 | 7 | /** 8 | * Created with IntelliJ IDEA. 9 | * Author: wangjie email:tiantian.china.2@gmial.com 10 | * Date: 13-12-10 11 | * Time: 下午5:07 12 | */ 13 | public class NestedGridView extends GridView{ 14 | 15 | public NestedGridView(Context context) { 16 | super(context); 17 | } 18 | 19 | public NestedGridView(Context context, AttributeSet attrs) { 20 | super(context, attrs); 21 | } 22 | 23 | public NestedGridView(Context context, AttributeSet attrs, int defStyle) { 24 | super(context, attrs, defStyle); 25 | } 26 | 27 | /** 28 | * 该自定义控件只是重写了GridView的onMeasure方法,使其不会出现滚动条,ScrollView嵌套ListView也是同样的道理,不再赘述。 29 | * @param widthMeasureSpec 30 | * @param heightMeasureSpec 31 | */ 32 | @Override 33 | public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 34 | 35 | int expandSpec = MeasureSpec.makeMeasureSpec( 36 | Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); 37 | super.onMeasure(widthMeasureSpec, expandSpec); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/NetworkResponse.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network; 2 | 3 | import com.wangjie.androidbucket.services.network.exception.HippoException; 4 | 5 | /** 6 | * @author Hubert He 7 | * @version V1.0 8 | * @Description 9 | * @Createdate 14-9-24 17:14 10 | */ 11 | public class NetworkResponse { 12 | 13 | private HippoException error; 14 | 15 | private byte[] data; 16 | 17 | public NetworkResponse() { 18 | this(null, null); 19 | } 20 | 21 | public NetworkResponse(HippoException error, byte[] data) { 22 | this.error = error; 23 | this.data = data; 24 | } 25 | 26 | public NetworkResponse(HippoException error) { 27 | this(error, null); 28 | } 29 | 30 | public NetworkResponse(byte[] data) { 31 | this(null, data); 32 | } 33 | 34 | public byte[] getData() { 35 | return data; 36 | } 37 | 38 | public void setData(byte[] data) { 39 | this.data = data; 40 | } 41 | 42 | public HippoException getError() { 43 | return error; 44 | } 45 | 46 | public void setError(HippoException error) { 47 | this.error = error; 48 | } 49 | 50 | public boolean isSuccess() { 51 | return error == null; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/present/ABFragment.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.present; 2 | 3 | import android.annotation.TargetApi; 4 | import android.app.Fragment; 5 | import android.os.Build; 6 | import com.wangjie.androidbucket.mvp.ABActivityViewer; 7 | import com.wangjie.androidbucket.mvp.ABBasePresenter; 8 | 9 | /** 10 | * Author: wangjie 11 | * Email: tiantian.china.2@gmail.com 12 | * Date: 8/30/14. 13 | */ 14 | @TargetApi(Build.VERSION_CODES.HONEYCOMB) 15 | @Deprecated 16 | public class ABFragment extends Fragment implements ABActivityViewer { 17 | 18 | @Override 19 | public void showToastMessage(String message) { 20 | } 21 | 22 | @Override 23 | public void showInfoDialog(String message) { 24 | } 25 | 26 | @Override 27 | public void showInfoDialog(String title, String message) { 28 | } 29 | 30 | @Override 31 | public void showLoadingDialog(String message) { 32 | } 33 | 34 | @Override 35 | public void cancelLoadingDialog() { 36 | } 37 | 38 | @Override 39 | public void showInfoDialog(String title, String message, String okButtonText) { 40 | } 41 | 42 | @Override 43 | public void registerPresenter(ABBasePresenter presenter) { 44 | } 45 | 46 | @Override 47 | public void closeAllTask() { 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/security/MD5.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.security; 2 | 3 | import com.wangjie.androidbucket.log.Logger; 4 | 5 | import java.security.MessageDigest; 6 | import java.security.NoSuchAlgorithmException; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: wangjie 11 | * Date: 14-3-27 12 | * Time: 下午9:18 13 | * To change this template use File | Settings | File Templates. 14 | */ 15 | public class MD5 { 16 | public static final String TAG = MD5.class.getSimpleName(); 17 | public static String md5(String str) { 18 | String result = null; 19 | try { 20 | MessageDigest md = MessageDigest.getInstance("MD5"); 21 | md.update(str.getBytes()); 22 | byte b[] = md.digest(); 23 | int i; 24 | StringBuffer buf = new StringBuffer(""); 25 | for (int offset = 0; offset < b.length; offset++) { 26 | i = b[offset]; 27 | if (i < 0) 28 | i += 256; 29 | if (i < 16) 30 | buf.append("0"); 31 | buf.append(Integer.toHexString(i)); 32 | } 33 | result = buf.toString(); //md5 32bit 34 | // result = buf.toString().substring(8, 24))); //md5 16bit 35 | } catch (NoSuchAlgorithmException e) { 36 | Logger.e(TAG, "MD5加密失败, ", e); 37 | } 38 | return result; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/system/ABPhone.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.system; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import com.wangjie.androidbucket.utils.ABTextUtil; 7 | 8 | /** 9 | * Created by wangjie on 6/10/14. 10 | */ 11 | public class ABPhone { 12 | 13 | /** 14 | * 拨打电话,直接拨打 15 | * 16 | * @param context 17 | * @param phoneNumber 18 | */ 19 | public static void call(Context context, String phoneNumber) { 20 | context.startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber))); 21 | } 22 | 23 | /** 24 | * 拨打电话,现实拨号界面 25 | * 26 | * @param context 27 | * @param phoneNumber 28 | */ 29 | public static void callDial(Context context, String phoneNumber) { 30 | context.startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber))); 31 | } 32 | 33 | /** 34 | * 发送短信息,跳转到发送短信界面 35 | * 36 | * @param context 37 | * @param phoneNumber 38 | * @param content 39 | */ 40 | public static void sendSms(Context context, String phoneNumber, String content) { 41 | Uri uri = Uri.parse("smsto:" + (ABTextUtil.isEmpty(phoneNumber) ? "": phoneNumber)); 42 | //Uri uri = Uri.parse("smsto:"); //不填写收件人 43 | Intent intent = new Intent(Intent.ACTION_SENDTO, uri); 44 | intent.putExtra("sms_body", ABTextUtil.isEmpty(content) ? "" : content); 45 | context.startActivity(intent); 46 | } 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/HippoResponse.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network; 2 | 3 | import com.wangjie.androidbucket.services.network.exception.HippoException; 4 | 5 | /** 6 | * @author Hubert He 7 | * @version V1.0 8 | * @Description 9 | * @Createdate 14-9-24 16:37 10 | */ 11 | public class HippoResponse { 12 | 13 | private HippoException error; 14 | 15 | private T result; 16 | 17 | public HippoResponse(T result) { 18 | this.result = result; 19 | this.error = null; 20 | } 21 | 22 | public HippoResponse(HippoException error) { 23 | this.error = error; 24 | } 25 | 26 | 27 | /** 28 | * Callback interface for delivering error responses. 29 | */ 30 | public abstract static class ErrorListener { 31 | /** 32 | * Callback method that an error has been occurred with the 33 | * provided error code and optional user-readable message. 34 | */ 35 | public abstract void onErrorResponse(HippoException error); 36 | 37 | /** 38 | * Process error message in background. 39 | */ 40 | public void onErrorProcessInBackground(HippoException error) { 41 | // Implement this if necessary 42 | } 43 | } 44 | 45 | 46 | public T getResult() { 47 | return result; 48 | } 49 | 50 | public boolean isSuccess() { 51 | return error == null; 52 | } 53 | 54 | public HippoException getError() { 55 | return error; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/watcher/OnTextCleanWatcher.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.watcher; 2 | 3 | import android.text.Editable; 4 | import android.text.TextWatcher; 5 | import android.view.View; 6 | import android.widget.EditText; 7 | import android.widget.ImageButton; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * Author: wangjie email:tiantian.china.2@gmail.com 12 | * Date: 13-10-14 13 | * Time: 下午12:31 14 | */ 15 | public class OnTextCleanWatcher implements TextWatcher, View.OnClickListener{ 16 | private EditText editText; 17 | private ImageButton cleanBtn; 18 | 19 | public OnTextCleanWatcher(EditText editText, ImageButton cleanBtn) { 20 | this.editText = editText; 21 | this.cleanBtn = cleanBtn; 22 | this.cleanBtn.setOnClickListener(this); 23 | this.editText.addTextChangedListener(this); 24 | } 25 | 26 | public EditText getEditText() { 27 | return editText; 28 | } 29 | 30 | public void setEditText(EditText editText) { 31 | this.editText = editText; 32 | } 33 | 34 | @Override 35 | public void beforeTextChanged(CharSequence s, int start, int count, int after) { 36 | } 37 | 38 | @Override 39 | public void onTextChanged(CharSequence s, int start, int before, int count) { 40 | cleanBtn.setVisibility(s.toString().equals("") ? View.GONE : View.VISIBLE); 41 | } 42 | 43 | @Override 44 | public void afterTextChanged(Editable s) { 45 | } 46 | 47 | @Override 48 | public void onClick(View v) { 49 | editText.setText(""); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/thread/ThreadPool.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.thread; 2 | 3 | import com.wangjie.androidbucket.log.Logger; 4 | 5 | import java.util.concurrent.ExecutorService; 6 | import java.util.concurrent.Executors; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email:tiantian.china.2@gmail.com 11 | * Date: 14-2-26 12 | * Time: 下午3:37 13 | */ 14 | public class ThreadPool { 15 | public static final String TAG = ThreadPool.class.getSimpleName(); 16 | static ExecutorService threadPool; 17 | 18 | public static void initThreadPool(int max){ // 可以在Application中进行配置 19 | if(max > 0){ 20 | max = max < 3 ? 3 : max; 21 | threadPool = Executors.newFixedThreadPool(max); 22 | }else{ 23 | threadPool = Executors.newCachedThreadPool(); 24 | } 25 | 26 | Logger.d(TAG, "[ThreadPool]ThreadPool init success...max thread: " + max); 27 | 28 | } 29 | 30 | public static ExecutorService getInstances(){ 31 | return threadPool; 32 | } 33 | 34 | public synchronized static void go(Runtask runtask){ 35 | if(null == threadPool){ 36 | Logger.e(TAG, "ThreadPool没有被初始化,请在Application中进行初始化操作..."); 37 | return; 38 | } 39 | // runtaskWeakReference.onBefore(); 40 | threadPool.execute(runtask); 41 | } 42 | 43 | public synchronized static void go(Runnable runnable){ 44 | if(null == threadPool){ 45 | Logger.e(TAG, "ThreadPool没有被初始化,请在Application中进行初始化操作..."); 46 | return; 47 | } 48 | threadPool.execute(runnable); 49 | } 50 | 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/verticalmenu/SheetItem.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.verticalmenu; 2 | 3 | import android.graphics.Color; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * Author: wangjie 9 | * Email: tiantian.china.2@gmail.com 10 | * Date: 12/10/14. 11 | */ 12 | public class SheetItem implements Serializable { 13 | private String title; 14 | private int textColor = Color.parseColor("#2198C8"); 15 | private int textSizeSp = 18; 16 | private int action; 17 | 18 | @Override 19 | public String toString() { 20 | return "SheetItem{" + 21 | "title='" + title + '\'' + 22 | ", textColor=" + textColor + 23 | ", textSizeSp=" + textSizeSp + 24 | ", action=" + action + 25 | '}'; 26 | } 27 | 28 | public String getTitle() { 29 | return title; 30 | } 31 | 32 | public SheetItem setTitle(String title) { 33 | this.title = title; 34 | return this; 35 | } 36 | 37 | public int getTextColor() { 38 | return textColor; 39 | } 40 | 41 | public SheetItem setTextColor(int textColor) { 42 | this.textColor = textColor; 43 | return this; 44 | } 45 | 46 | public int getTextSizeSp() { 47 | return textSizeSp; 48 | } 49 | 50 | public SheetItem setTextSizeSp(int textSizeSp) { 51 | this.textSizeSp = textSizeSp; 52 | return this; 53 | } 54 | 55 | public int getAction() { 56 | return action; 57 | } 58 | 59 | public SheetItem setAction(int action) { 60 | this.action = action; 61 | return this; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/system/WakeLocker.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.system; 2 | 3 | import android.content.Context; 4 | import android.os.PowerManager; 5 | import com.wangjie.androidbucket.log.Logger; 6 | 7 | /** 8 | * 唤醒和释放手机 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email:tiantian.china.2@gmail.com 11 | * Date: 13-7-31 12 | * Time: 上午10:24 13 | */ 14 | public abstract class WakeLocker { 15 | private static final String TAG = WakeLocker.class.getSimpleName(); 16 | private static PowerManager.WakeLock wakeLock; 17 | 18 | public static void acquire(Context ctx) { 19 | if (wakeLock != null) wakeLock.release(); 20 | 21 | PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE); 22 | // wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | 23 | // PowerManager.ACQUIRE_CAUSES_WAKEUP | 24 | // PowerManager.ON_AFTER_RELEASE, "TAG"); 25 | wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "TAG"); 26 | wakeLock.acquire(); 27 | } 28 | 29 | public static void release() { 30 | 31 | synchronized (WakeLocker.class) { 32 | // sanity check for null as this is a public method 33 | if (wakeLock != null) { 34 | try { 35 | wakeLock.release(); 36 | } catch (Throwable th) { 37 | // ignoring this exception, probably wakeLock was already released 38 | Logger.e(TAG, "ignoring this exception, probably wakeLock was already released, ", th); 39 | } 40 | } 41 | wakeLock = null; 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/recyclerview/adapter/ABRecyclerViewTypeAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.recyclerview.adapter; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.view.ViewGroup; 7 | import com.wangjie.androidbucket.R; 8 | import com.wangjie.androidbucket.adapter.typeadapter.ABAdapterTypeRender; 9 | 10 | /** 11 | * Author: wangjie 12 | * Email: tiantian.china.2@gmail.com 13 | * Date: 1/19/15. 14 | */ 15 | public abstract class ABRecyclerViewTypeAdapter extends RecyclerView.Adapter { 16 | @TargetApi(Build.VERSION_CODES.DONUT) 17 | @Override 18 | public ABRecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 19 | ABAdapterTypeRender render = getAdapterTypeRender(viewType); 20 | ABRecyclerViewHolder holder = render.getReusableComponent(); 21 | holder.itemView.setTag(R.id.ab__id_adapter_item_type_render, render); 22 | render.fitEvents(); 23 | return holder; 24 | } 25 | 26 | @TargetApi(Build.VERSION_CODES.DONUT) 27 | @Override 28 | public void onBindViewHolder(ABRecyclerViewHolder holder, int position) { 29 | ABAdapterTypeRender render = (ABAdapterTypeRender) holder.itemView.getTag(R.id.ab__id_adapter_item_type_render); 30 | render.fitDatas(position); 31 | } 32 | 33 | /** 34 | * 根据指定position的item获取对应的type,然后通过type实例化一个AdapterTypeRender的实现 35 | * 36 | * @return 37 | */ 38 | public abstract ABAdapterTypeRender getAdapterTypeRender(int type); 39 | } 40 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/VerticalScrollView.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.MotionEvent; 6 | import android.widget.ScrollView; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email:tiantian.china.2@gmail.com 11 | * Date: 14-4-13 12 | * Time: 上午10:49 13 | */ 14 | public class VerticalScrollView extends ScrollView { 15 | public VerticalScrollView(Context context) { 16 | super(context); 17 | } 18 | 19 | public VerticalScrollView(Context context, AttributeSet attrs) { 20 | super(context, attrs); 21 | } 22 | 23 | public VerticalScrollView(Context context, AttributeSet attrs, int defStyle) { 24 | super(context, attrs, defStyle); 25 | } 26 | 27 | @Override 28 | public boolean onInterceptTouchEvent(MotionEvent ev) { 29 | final int action = ev.getAction(); 30 | switch (action) { 31 | case MotionEvent.ACTION_DOWN: 32 | super.onTouchEvent(ev); 33 | break; 34 | 35 | case MotionEvent.ACTION_MOVE: 36 | return false; // redirect MotionEvents to ourself 37 | 38 | case MotionEvent.ACTION_CANCEL: 39 | super.onTouchEvent(ev); 40 | break; 41 | 42 | case MotionEvent.ACTION_UP: 43 | return false; 44 | 45 | default: 46 | break; 47 | } 48 | 49 | return false; 50 | } 51 | 52 | @Override 53 | public boolean onTouchEvent(MotionEvent ev) { 54 | super.onTouchEvent(ev); 55 | return true; 56 | } 57 | } -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/recyclerview/adapter/ABRecyclerViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.recyclerview.adapter; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.util.SparseArray; 5 | import android.view.View; 6 | import com.wangjie.androidbucket.log.Logger; 7 | 8 | /** 9 | * Author: wangjie 10 | * Email: tiantian.china.2@gmail.com 11 | * Date: 1/19/15. 12 | */ 13 | public class ABRecyclerViewHolder extends RecyclerView.ViewHolder { 14 | private static final String TAG = ABRecyclerViewHolder.class.getSimpleName(); 15 | private SparseArray holder = null; 16 | 17 | public ABRecyclerViewHolder(View itemView) { 18 | super(itemView); 19 | } 20 | 21 | /** 22 | * 获取一个缓存的view 23 | * 24 | * @param id 25 | * @param 26 | * @return 27 | */ 28 | public T obtainView(int id) { 29 | if (null == holder) { 30 | holder = new SparseArray<>(); 31 | } 32 | View view = holder.get(id); 33 | if (null != view) { 34 | return (T) view; 35 | } 36 | view = itemView.findViewById(id); 37 | if (null == view) { 38 | Logger.e(TAG, "no view that id is " + id); 39 | return null; 40 | } 41 | holder.put(id, view); 42 | return (T) view; 43 | } 44 | 45 | /** 46 | * 获取一个缓存的view,并自动转型 47 | * 48 | * @param id 49 | * @param 50 | * @return 51 | */ 52 | public T obtainView(int id, Class viewClazz) { 53 | View view = obtainView(id); 54 | if (null == view) { 55 | return null; 56 | } 57 | return (T) view; 58 | } 59 | 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/typeadapter/BaseTypeAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter.typeadapter; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | import android.widget.ListView; 9 | import com.wangjie.androidbucket.R; 10 | import com.wangjie.androidbucket.adapter.ABaseAdapter; 11 | 12 | /** 13 | * Author: wangjie 14 | * Email: tiantian.china.2@gmail.com 15 | * Date: 9/25/14. 16 | */ 17 | public abstract class BaseTypeAdapter extends ABaseAdapter { 18 | protected BaseTypeAdapter(ListView listView) { 19 | super(listView); 20 | } 21 | 22 | @TargetApi(Build.VERSION_CODES.DONUT) 23 | @Override 24 | public View getView(int position, View convertView, ViewGroup parent) { 25 | AdapterTypeRender typeRender; 26 | if (null == convertView) { 27 | typeRender = getAdapterTypeRender(position); 28 | convertView = typeRender.getConvertView(); 29 | convertView.setTag(R.id.ab__id_adapter_item_type_render, typeRender); 30 | typeRender.fitEvents(); 31 | } else { 32 | typeRender = (AdapterTypeRender) convertView.getTag(R.id.ab__id_adapter_item_type_render); 33 | } 34 | convertView.setTag(R.id.ab__id_adapter_item_position, position); 35 | 36 | if (null != typeRender) { 37 | typeRender.fitDatas(position); 38 | } 39 | 40 | return convertView; 41 | } 42 | 43 | /** 44 | * 根据指定position的item获取对应的type,然后通过type实例化一个AdapterTypeRender的实现 45 | * 46 | * @param position 47 | * @return 48 | */ 49 | public abstract AdapterTypeRender getAdapterTypeRender(int position); 50 | } 51 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/present/ABSupportFragment.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.present; 2 | 3 | import android.app.AlertDialog; 4 | import android.support.v4.app.Fragment; 5 | import android.widget.Toast; 6 | import com.wangjie.androidbucket.mvp.ABActivityViewer; 7 | import com.wangjie.androidbucket.mvp.ABBasePresenter; 8 | 9 | /** 10 | * Created by wangjie on 6/15/14. 11 | */ 12 | public class ABSupportFragment extends Fragment implements ABActivityViewer{ 13 | 14 | private ABBasePresenter presenter; 15 | 16 | @Override 17 | public void showToastMessage(String msg) { 18 | Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show(); 19 | } 20 | 21 | @Override 22 | public void showInfoDialog(String message) { 23 | showInfoDialog(null, message); 24 | } 25 | 26 | @Override 27 | public void showInfoDialog(String title, String message) { 28 | new AlertDialog.Builder(getActivity()) 29 | .setTitle(title) 30 | .setMessage(message) 31 | .setPositiveButton("OK", null) 32 | .show(); 33 | } 34 | 35 | @Override 36 | public void showLoadingDialog(String message) { 37 | 38 | } 39 | 40 | @Override 41 | public void cancelLoadingDialog() { 42 | 43 | } 44 | 45 | @Override 46 | public void showInfoDialog(String title, String message, String okButtonText) { 47 | new AlertDialog.Builder(getActivity()) 48 | .setTitle(title) 49 | .setMessage(message) 50 | .setPositiveButton(okButtonText, null) 51 | .show(); 52 | } 53 | 54 | @Override 55 | public void registerPresenter(ABBasePresenter presenter) { 56 | this.presenter = presenter; 57 | } 58 | 59 | @Override 60 | public void closeAllTask() { 61 | if(null != presenter){ 62 | presenter.closeAllTask(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/dropdownmenu/DropMenuAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.dropdownmenu; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | import android.widget.TextView; 9 | import com.wangjie.androidbucket.R; 10 | 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | /** 15 | * Created with IntelliJ IDEA. 16 | * Author: wangjie email:tiantian.china.2@gmail.com 17 | * Date: 14-3-26 18 | * Time: 下午5:31 19 | */ 20 | public class DropMenuAdapter extends BaseAdapter{ 21 | Context context; 22 | List> list; 23 | private int itemSelectorBg; 24 | 25 | public DropMenuAdapter(Context context, List> list, int itemSelectorBg) { 26 | this.context = context; 27 | this.list = list; 28 | this.itemSelectorBg = itemSelectorBg; 29 | } 30 | 31 | @Override 32 | public int getCount() { 33 | return list.size(); 34 | } 35 | 36 | @Override 37 | public Object getItem(int position) { 38 | return list.get(position); 39 | } 40 | 41 | @Override 42 | public long getItemId(int position) { 43 | return position; 44 | } 45 | 46 | @Override 47 | public View getView(int position, View convertView, ViewGroup parent) { 48 | ViewHolder holder; 49 | if(null == convertView){ 50 | holder = new ViewHolder(); 51 | convertView = LayoutInflater.from(context).inflate(R.layout.ab_drop_menu_item, null); 52 | holder.title = (TextView) convertView.findViewById(R.id.ab_drop_menu_item_title); 53 | holder.title.setBackgroundResource(itemSelectorBg); 54 | convertView.setTag(holder); 55 | }else{ 56 | holder = (ViewHolder) convertView.getTag(); 57 | } 58 | holder.title.setText(list.get(position).get(DropMenu.KEY_TITLE)); 59 | return convertView; 60 | } 61 | 62 | class ViewHolder{ 63 | TextView title; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/http/HttpConfig.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network.http; 2 | 3 | /** 4 | * @author Hubert He 5 | * @version V1.0 6 | * @Description Http配置 默认HTTP端口80,HTTPS端口9000,SO超时时间20秒,连接超时时间20秒 7 | * @Createdate 14-9-4 15:14 8 | */ 9 | public class HttpConfig { 10 | 11 | // HTTP Port 12 | private int httpPort; 13 | 14 | // HTTPS Port 15 | private int httpsPort; 16 | 17 | // So超时时间 18 | private int soTimeout; 19 | 20 | // 连接超时时间 21 | private int connectionTimeout; 22 | 23 | // Domain 24 | private String domain; 25 | 26 | /** 27 | * 默认构造函数 28 | */ 29 | public HttpConfig() { 30 | this("", 80, 9000, 20000, 20000); 31 | } 32 | 33 | public HttpConfig(String domain, int httpPort, int httpsPort, int soTimeout, int connectionTimeout) { 34 | this.domain = domain; 35 | this.httpPort = httpPort; 36 | this.httpsPort = httpsPort; 37 | this.soTimeout = soTimeout; 38 | this.connectionTimeout = connectionTimeout; 39 | } 40 | 41 | public HttpConfig(String domain, int soTimeout, int connectionTimeout) { 42 | this(domain, 80, 443, soTimeout, connectionTimeout); 43 | } 44 | 45 | public int getSoTimeout() { 46 | return soTimeout; 47 | } 48 | 49 | public void setSoTimeout(int soTimeout) { 50 | this.soTimeout = soTimeout; 51 | } 52 | 53 | public int getConnectionTimeout() { 54 | return connectionTimeout; 55 | } 56 | 57 | public void setConnectionTimeout(int connectionTimeout) { 58 | this.connectionTimeout = connectionTimeout; 59 | } 60 | 61 | public int getHttpPort() { 62 | return httpPort; 63 | } 64 | 65 | public void setHttpPort(int httpPort) { 66 | this.httpPort = httpPort; 67 | } 68 | 69 | public int getHttpsPort() { 70 | return httpsPort; 71 | } 72 | 73 | public void setHttpsPort(int httpsPort) { 74 | this.httpsPort = httpsPort; 75 | } 76 | 77 | public String getDomain() { 78 | return domain; 79 | } 80 | 81 | public void setDomain(String domain) { 82 | this.domain = domain; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/verticalmenu/SheetAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.verticalmenu; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | import android.widget.TextView; 9 | import com.wangjie.androidbucket.R; 10 | import com.wangjie.androidbucket.utils.ABTextUtil; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * Created with IntelliJ IDEA. 16 | * Author: wangjie email:tiantian.china.2@gmail.com 17 | * Date: 14-3-26 18 | * Time: 下午5:31 19 | */ 20 | public class SheetAdapter extends BaseAdapter { 21 | Context context; 22 | List list; 23 | private int itemSelectorBg; 24 | 25 | public SheetAdapter(Context context, List list, int itemSelectorBg) { 26 | this.context = context; 27 | this.list = list; 28 | this.itemSelectorBg = itemSelectorBg; 29 | } 30 | 31 | @Override 32 | public int getCount() { 33 | return list.size(); 34 | } 35 | 36 | @Override 37 | public Object getItem(int position) { 38 | return list.get(position); 39 | } 40 | 41 | @Override 42 | public long getItemId(int position) { 43 | return position; 44 | } 45 | 46 | @Override 47 | public View getView(int position, View convertView, ViewGroup parent) { 48 | ViewHolder holder; 49 | if (null == convertView) { 50 | holder = new ViewHolder(); 51 | convertView = LayoutInflater.from(context).inflate(R.layout.ab_sheet_item, null); 52 | holder.title = (TextView) convertView.findViewById(R.id.ab_sheet_item_title_tv); 53 | holder.title.setBackgroundResource(itemSelectorBg > 0 ? itemSelectorBg : R.drawable.selector_bg_sheet_item); 54 | int padding = ABTextUtil.dip2px(context, 12); 55 | holder.title.setPadding(padding, padding, padding, padding); 56 | convertView.setTag(holder); 57 | } else { 58 | holder = (ViewHolder) convertView.getTag(); 59 | } 60 | holder.title.setText(list.get(position)); 61 | return convertView; 62 | } 63 | 64 | class ViewHolder { 65 | TextView title; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/verticalmenu/SheetComplexAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.verticalmenu; 2 | 3 | import android.content.Context; 4 | import android.util.TypedValue; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.BaseAdapter; 9 | import android.widget.TextView; 10 | import com.wangjie.androidbucket.R; 11 | import com.wangjie.androidbucket.utils.ABTextUtil; 12 | 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * Created with IntelliJ IDEA. 18 | * Author: wangjie email:tiantian.china.2@gmail.com 19 | * Date: 14-3-26 20 | * Time: 下午5:31 21 | */ 22 | public class SheetComplexAdapter extends BaseAdapter { 23 | Context context; 24 | List list; 25 | private int itemSelectorBg; 26 | 27 | public SheetComplexAdapter(Context context, List list, int itemSelectorBg) { 28 | this.context = context; 29 | this.list = list; 30 | this.itemSelectorBg = itemSelectorBg; 31 | } 32 | 33 | @Override 34 | public int getCount() { 35 | return list.size(); 36 | } 37 | 38 | @Override 39 | public Object getItem(int position) { 40 | return list.get(position); 41 | } 42 | 43 | @Override 44 | public long getItemId(int position) { 45 | return position; 46 | } 47 | 48 | @Override 49 | public View getView(int position, View convertView, ViewGroup parent) { 50 | if (null == convertView) { 51 | convertView = LayoutInflater.from(context).inflate(R.layout.ab_sheet_item, null); 52 | } 53 | 54 | TextView titleTv = (TextView) convertView.findViewById(R.id.ab_sheet_item_title_tv); 55 | 56 | SheetItem sheetItem = list.get(position); 57 | 58 | titleTv.setBackgroundResource(itemSelectorBg > 0 ? itemSelectorBg : R.drawable.selector_bg_sheet_item); 59 | int padding = ABTextUtil.dip2px(context, 12); 60 | titleTv.setPadding(padding, padding, padding, padding); 61 | titleTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, sheetItem.getTextSizeSp()); 62 | titleTv.setTextColor(sheetItem.getTextColor()); 63 | titleTv.setText(sheetItem.getTitle()); 64 | return convertView; 65 | } 66 | 67 | 68 | } 69 | -------------------------------------------------------------------------------- /res/layout/ab_sheet.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 26 | 27 | 30 | 31 | 32 | 33 | 40 | 41 | 42 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/http/SSLSocketFactoryEx.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network.http; 2 | 3 | import org.apache.http.conn.ssl.SSLSocketFactory; 4 | 5 | import javax.net.ssl.SSLContext; 6 | import javax.net.ssl.TrustManager; 7 | import javax.net.ssl.X509TrustManager; 8 | import java.io.IOException; 9 | import java.net.Socket; 10 | import java.security.*; 11 | 12 | /** 13 | * @author Hubert He 14 | * @version V1.0 15 | * @Description 按照 http://www.eoeandroid.com/thread-161747-1-1.html 给出方案实现SSL访问 16 | * @Createdate 14-9-4 14:33 17 | */ 18 | public class SSLSocketFactoryEx extends SSLSocketFactory { 19 | SSLContext sslContext = SSLContext.getInstance("TLS"); 20 | 21 | /** 22 | * 构造函数 23 | * 24 | * @param keyStore 25 | * @throws NoSuchAlgorithmException 26 | * @throws KeyManagementException 27 | * @throws KeyStoreException 28 | * @throws UnrecoverableKeyException 29 | */ 30 | public SSLSocketFactoryEx(KeyStore keyStore) 31 | throws NoSuchAlgorithmException, KeyManagementException, 32 | KeyStoreException, UnrecoverableKeyException { 33 | super(keyStore); 34 | 35 | TrustManager tm = new X509TrustManager() { 36 | public java.security.cert.X509Certificate[] getAcceptedIssuers() { 37 | return null; 38 | } 39 | 40 | @Override 41 | public void checkClientTrusted( 42 | java.security.cert.X509Certificate[] chain, String authType) 43 | throws java.security.cert.CertificateException { 44 | } 45 | 46 | @Override 47 | public void checkServerTrusted( 48 | java.security.cert.X509Certificate[] chain, String authType) 49 | throws java.security.cert.CertificateException { 50 | } 51 | }; 52 | sslContext.init(null, new TrustManager[]{tm}, null); 53 | } 54 | 55 | @Override 56 | public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException { 57 | return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); 58 | } 59 | 60 | @Override 61 | public Socket createSocket() throws IOException { 62 | return sslContext.getSocketFactory().createSocket(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/ABaseHolderAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter; 2 | 3 | import android.content.Context; 4 | import android.util.SparseArray; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.BaseAdapter; 9 | 10 | /** 11 | * 实现对BaseAdapter中ViewHolder相关的简化 12 | * Created with IntelliJ IDEA. 13 | * Author: wangjie email:tiantian.china.2@gmail.com 14 | * Date: 14-4-2 15 | * Time: 下午5:54 16 | */ 17 | public abstract class ABaseHolderAdapter extends BaseAdapter{ 18 | Context context; 19 | 20 | protected ABaseHolderAdapter(Context context) { 21 | this.context = context; 22 | } 23 | 24 | protected ABaseHolderAdapter() { 25 | } 26 | 27 | /** 28 | * 各个控件的缓存 29 | */ 30 | class ViewHolder{ 31 | public SparseArray views = new SparseArray(); 32 | 33 | /** 34 | * 指定resId和类型即可获取到相应的view 35 | * @param convertView 36 | * @param resId 37 | * @param 38 | * @return 39 | */ 40 | T obtainView(View convertView, int resId){ 41 | View v = views.get(resId); 42 | if(null == v){ 43 | v = convertView.findViewById(resId); 44 | views.put(resId, v); 45 | } 46 | return (T)v; 47 | } 48 | 49 | } 50 | 51 | /** 52 | * 改方法需要子类实现,需要返回item布局的resource id 53 | * @return 54 | */ 55 | public abstract int itemLayoutRes(); 56 | 57 | @Override 58 | public View getView(int position, View convertView, ViewGroup parent) { 59 | ViewHolder holder; 60 | if(null == convertView){ 61 | holder = new ViewHolder(); 62 | convertView = LayoutInflater.from(context).inflate(itemLayoutRes(), null); 63 | convertView.setTag(holder); 64 | }else{ 65 | holder = (ViewHolder) convertView.getTag(); 66 | } 67 | return getView(position, convertView, parent, holder); 68 | } 69 | 70 | /** 71 | * 使用该getView方法替换原来的getView方法,需要子类实现 72 | * @param position 73 | * @param convertView 74 | * @param parent 75 | * @param holder 76 | * @return 77 | */ 78 | public abstract View getView(int position, View convertView, ViewGroup parent, ViewHolder holder); 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/drawable/InnerBorderDrawable.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.drawable; 2 | 3 | import android.graphics.*; 4 | import android.graphics.drawable.Drawable; 5 | 6 | /** 7 | * Author: wangjie 8 | * Email: tiantian.china.2@gmail.com 9 | * Date: 1/13/15. 10 | */ 11 | public class InnerBorderDrawable extends Drawable { 12 | protected Paint paint = new Paint(); 13 | protected RectF drawArea = new RectF(); 14 | protected float border; // 边框宽度 15 | protected float corner; // 圆角大小 16 | protected int fillColor; // 填充颜色 17 | protected int borderColor; // 边框颜色 18 | 19 | public InnerBorderDrawable() { 20 | } 21 | 22 | public InnerBorderDrawable(int borderColor, int fillColor, float corner, float border) { 23 | this.borderColor = borderColor; 24 | this.fillColor = fillColor; 25 | this.corner = corner; 26 | this.border = border; 27 | } 28 | 29 | @Override 30 | protected void onBoundsChange(Rect bounds) { 31 | super.onBoundsChange(bounds); 32 | drawArea.left = bounds.left + border; 33 | drawArea.top = bounds.top + border; 34 | drawArea.right = bounds.right - border; 35 | drawArea.bottom = bounds.bottom - border; 36 | } 37 | 38 | @Override 39 | public void draw(Canvas canvas) { 40 | // fill 41 | paint.setStyle(Paint.Style.FILL); 42 | paint.setColor(fillColor); 43 | canvas.drawRoundRect(drawArea, corner, corner, paint); 44 | 45 | if (border > 0) { 46 | // border 47 | paint.setStyle(Paint.Style.STROKE); 48 | paint.setColor(borderColor); 49 | paint.setStrokeWidth(border); 50 | canvas.drawRoundRect(drawArea, corner, corner, paint); 51 | } 52 | 53 | } 54 | 55 | @Override 56 | public void setAlpha(int alpha) { 57 | } 58 | 59 | @Override 60 | public void setColorFilter(ColorFilter cf) { 61 | } 62 | 63 | @Override 64 | public int getOpacity() { 65 | return 0; 66 | } 67 | 68 | public void setBorderColor(int borderColor) { 69 | this.borderColor = borderColor; 70 | } 71 | 72 | public void setFillColor(int fillColor) { 73 | this.fillColor = fillColor; 74 | } 75 | 76 | public void setCorner(float corner) { 77 | this.corner = corner; 78 | } 79 | 80 | public void setBorder(float border) { 81 | this.border = border; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/TextCopy.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.util.AttributeSet; 6 | import android.view.ContextMenu; 7 | import android.view.Gravity; 8 | import android.widget.EditText; 9 | 10 | 11 | /** 12 | * 可选择复制的TextView 13 | * Created with IntelliJ IDEA. 14 | * Author: wangjie email:tiantian.china.2@gmail.com 15 | * Date: 13-8-2 16 | * Time: 下午4:27 17 | */ 18 | public class TextCopy extends EditText { 19 | private int off; //字符串的偏移值 20 | 21 | public TextCopy(Context context) { 22 | super(context); 23 | initialize(); 24 | } 25 | 26 | public TextCopy(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | initialize(); 29 | } 30 | 31 | public TextCopy(Context context, AttributeSet attrs, int defStyle) { 32 | super(context, attrs, defStyle); 33 | initialize(); 34 | } 35 | 36 | private void initialize() { 37 | setGravity(Gravity.TOP); 38 | // setBackgroundColor(Color.TRANSPARENT); 39 | // setBackground(null); 40 | // setTextIsSelectable(true); 41 | setHighlightColor(Color.parseColor("#33B5E5")); 42 | } 43 | 44 | @Override 45 | protected void onCreateContextMenu(ContextMenu menu) { 46 | //不做任何处理,为了阻止长按的时候弹出上下文菜单 47 | } 48 | 49 | @Override 50 | public boolean getDefaultEditable() { 51 | return false; 52 | } 53 | 54 | // @Override 55 | // public boolean onTouchEvent(MotionEvent event) { 56 | // int action = event.getAction(); 57 | // Layout layout = getLayout(); 58 | // int line = 0; 59 | // switch(action) { 60 | // case MotionEvent.ACTION_DOWN: 61 | // line = layout.getLineForVertical(getScrollY()+ (int)event.getY()); 62 | // off = layout.getOffsetForHorizontal(line, (int)event.getX()); 63 | // Selection.setSelection(getEditableText(), off); 64 | // break; 65 | // case MotionEvent.ACTION_MOVE: 66 | // case MotionEvent.ACTION_UP: 67 | // line = layout.getLineForVertical(getScrollY()+(int)event.getY()); 68 | // int curOff = layout.getOffsetForHorizontal(line, (int)event.getX()); 69 | // Selection.setSelection(getEditableText(), off, curOff); 70 | // break; 71 | // } 72 | // return true; 73 | // } 74 | } 75 | -------------------------------------------------------------------------------- /res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/application/ABApplication.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.application; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import com.wangjie.androidbucket.exception.ABCrashHandler; 6 | import com.wangjie.androidbucket.log.Logger; 7 | import com.wangjie.androidbucket.services.network.http.ABHttpUtil; 8 | import com.wangjie.androidbucket.thread.ThreadPool; 9 | import com.wangjie.androidbucket.utils.ABPrefsUtil; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * Author: wangjie email:tiantian.china.2@gmail.com 14 | * Date: 14-3-26 15 | * Time: 下午4:37 16 | */ 17 | public class ABApplication extends Application { 18 | 19 | private static ABApplication instance; 20 | 21 | public static ABApplication getInstance() { 22 | return instance; 23 | } 24 | 25 | @Override 26 | public void onCreate() { 27 | super.onCreate(); 28 | instance = this; 29 | initLogger(); // 初始化日志工具 30 | initThreadPool(); // 初始化线程池 31 | initNetWorkSSLScheme(); // 初始化AINetWork中SSL Scheme 32 | initImageLoader(); // 初始化图片加载器 33 | initCrashHandler(); // 初始化程序崩溃捕捉处理 34 | initPrefs(); // 初始化SharedPreference 35 | initABActionbar(); // 初始化Actionbar配置 36 | // 初始化Http连接 37 | initHttpConfig(); 38 | } 39 | 40 | /** 41 | * 初始化线程池 42 | */ 43 | protected void initThreadPool() { 44 | ThreadPool.initThreadPool(-1); 45 | } 46 | 47 | /** 48 | * 初始化AINetWork中SSL Scheme 49 | */ 50 | protected void initNetWorkSSLScheme() { 51 | } 52 | 53 | /** 54 | * 初始化日志 55 | */ 56 | protected void initLogger() { 57 | Logger.initLogger(null); 58 | } 59 | 60 | /** 61 | * 初始化图片加载器(子类需要重写) 62 | */ 63 | protected void initImageLoader() { 64 | 65 | } 66 | 67 | /** 68 | * 初始化程序崩溃捕捉处理 69 | */ 70 | protected void initCrashHandler() { 71 | ABCrashHandler.init(getApplicationContext()); 72 | } 73 | 74 | /** 75 | * 初始化SharedPreference 76 | */ 77 | protected void initPrefs() { 78 | ABPrefsUtil.init(getApplicationContext(), getPackageName() + "_preference", Context.MODE_MULTI_PROCESS); 79 | } 80 | 81 | /** 82 | * 初始化Actionbar配置(如果要使用Actionbar,则需要子类重写) 83 | */ 84 | protected void initABActionbar() { 85 | 86 | } 87 | 88 | protected void initHttpConfig() { 89 | ABHttpUtil.initHttpConfig(null, null); 90 | } 91 | 92 | 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/drawable/CircleDrawable.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.drawable; 2 | 3 | import android.graphics.Canvas; 4 | import android.graphics.ColorFilter; 5 | import android.graphics.Paint; 6 | import android.graphics.Rect; 7 | import android.graphics.drawable.Drawable; 8 | 9 | /** 10 | * Author: wangjie 11 | * Email: tiantian.china.2@gmail.com 12 | * Date: 1/13/15. 13 | */ 14 | public class CircleDrawable extends Drawable { 15 | protected Paint paint = new Paint(); 16 | protected float border; // 边框宽度 17 | protected int fillColor; // 填充颜色 18 | protected int borderColor; // 边框颜色 19 | 20 | float circleX; // 圆心 21 | float circleY; 22 | float radius; // 半径 23 | 24 | public CircleDrawable() { 25 | } 26 | 27 | public CircleDrawable(int borderColor, int fillColor, float border) { 28 | this(borderColor, fillColor, border, 0); 29 | } 30 | 31 | public CircleDrawable(int borderColor, int fillColor, float border, int drawRadius) { 32 | this.borderColor = borderColor; 33 | this.fillColor = fillColor; 34 | this.border = border; 35 | this.radius = drawRadius; 36 | 37 | paint.setAntiAlias(true); 38 | paint.setTextAlign(Paint.Align.CENTER); 39 | } 40 | 41 | @Override 42 | protected void onBoundsChange(Rect bounds) { 43 | super.onBoundsChange(bounds); 44 | circleX = (bounds.left + bounds.right) / 2; 45 | circleY = (bounds.top + bounds.bottom) / 2; 46 | if (radius <= 0) { 47 | int circleSize = Math.min(bounds.right - bounds.left, bounds.bottom - bounds.top); 48 | radius = (circleSize - 2 * border) / 2; 49 | } 50 | } 51 | 52 | @Override 53 | public void draw(Canvas canvas) { 54 | // fill 55 | paint.setStyle(Paint.Style.FILL); 56 | paint.setColor(fillColor); 57 | canvas.drawCircle(circleX, circleY, radius, paint); 58 | 59 | if (border > 0) { 60 | // border 61 | paint.setStyle(Paint.Style.STROKE); 62 | paint.setColor(borderColor); 63 | paint.setStrokeWidth(border); 64 | canvas.drawCircle(circleX, circleY, radius, paint); 65 | } 66 | 67 | } 68 | 69 | @Override 70 | public void setAlpha(int alpha) { 71 | } 72 | 73 | @Override 74 | public void setColorFilter(ColorFilter cf) { 75 | } 76 | 77 | @Override 78 | public int getOpacity() { 79 | return 0; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/WrapContentHeightViewPager.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews; 2 | 3 | import android.content.Context; 4 | import android.support.v4.view.ViewPager; 5 | import android.util.AttributeSet; 6 | import android.view.View; 7 | 8 | /** 9 | * 支持自适应的ViewPager,来自:http://stackoverflow.com/questions/8394681/android-i-am-unable-to-have-viewpager-wrap-content/18167273#18167273 10 | * Created by wangjie on 6/12/14. 11 | */ 12 | public class WrapContentHeightViewPager extends ViewPager { 13 | 14 | /** 15 | * Constructor 16 | * 17 | * @param context the context 18 | */ 19 | public WrapContentHeightViewPager(Context context) { 20 | super(context); 21 | } 22 | 23 | /** 24 | * Constructor 25 | * 26 | * @param context the context 27 | * @param attrs the attribute set 28 | */ 29 | public WrapContentHeightViewPager(Context context, AttributeSet attrs) { 30 | super(context, attrs); 31 | } 32 | 33 | @Override 34 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 35 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 36 | 37 | // find the first child view 38 | View view = getChildAt(0); 39 | if (view != null) { 40 | // measure the first child view with the specified measure spec 41 | view.measure(widthMeasureSpec, heightMeasureSpec); 42 | } 43 | 44 | setMeasuredDimension(getMeasuredWidth(), measureHeight(heightMeasureSpec, view)); 45 | } 46 | 47 | /** 48 | * Determines the height of this view 49 | * 50 | * @param measureSpec A measureSpec packed into an int 51 | * @param view the base view with already measured height 52 | * 53 | * @return The height of the view, honoring constraints from measureSpec 54 | */ 55 | private int measureHeight(int measureSpec, View view) { 56 | int result = 0; 57 | int specMode = MeasureSpec.getMode(measureSpec); 58 | int specSize = MeasureSpec.getSize(measureSpec); 59 | 60 | if (specMode == MeasureSpec.EXACTLY) { 61 | result = specSize; 62 | } else { 63 | // set the height from the base view if available 64 | if (view != null) { 65 | result = view.getMeasuredHeight(); 66 | } 67 | if (specMode == MeasureSpec.AT_MOST) { 68 | result = Math.min(result, specSize); 69 | } 70 | } 71 | return result; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/borderscrollview/BorderScrollView.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.borderscrollview; 2 | 3 | import android.content.Context; 4 | import android.graphics.Rect; 5 | import android.util.AttributeSet; 6 | import android.widget.ScrollView; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email:tiantian.china.2@gmail.com 11 | * Date: 13-9-6 12 | * Time: 下午2:06 13 | */ 14 | public class BorderScrollView extends ScrollView{ 15 | private long millis; 16 | // 滚动监听者 17 | private OnScrollChangedListener onScrollChangedListener; 18 | 19 | public BorderScrollView(Context context) { 20 | super(context); 21 | } 22 | 23 | public BorderScrollView(Context context, AttributeSet attrs) { 24 | super(context, attrs); 25 | } 26 | 27 | public BorderScrollView(Context context, AttributeSet attrs, int defStyle) { 28 | super(context, attrs, defStyle); 29 | } 30 | 31 | @Override 32 | protected void onScrollChanged(int l, int t, int oldl, int oldt) { 33 | super.onScrollChanged(l, t, oldl, oldt); 34 | long now = System.currentTimeMillis(); 35 | 36 | if(null == onScrollChangedListener){ 37 | return; 38 | } 39 | 40 | // 通知监听者 41 | onScrollChangedListener.onScrollChanged(l, t, oldl, oldt); 42 | 43 | if(now - millis > 1000l){ 44 | // 滚动到底部(前提:从不是底部滚动到底部) 45 | if((this.getHeight() + oldt) != this.getTotalVerticalScrollRange() 46 | && (this.getHeight() + t) == this.getTotalVerticalScrollRange()){ 47 | onScrollChangedListener.onScrollBottom(); 48 | 49 | millis = now; 50 | } 51 | } 52 | 53 | 54 | if(oldt != 0 && t == 0){ 55 | onScrollChangedListener.onScrollTop(); 56 | } 57 | 58 | 59 | } 60 | 61 | public OnScrollChangedListener getOnScrollChangedListener() { 62 | return onScrollChangedListener; 63 | } 64 | 65 | public void setOnScrollChangedListener(OnScrollChangedListener onScrollChangedListener) { 66 | this.onScrollChangedListener = onScrollChangedListener; 67 | } 68 | 69 | /** 70 | * 获得滚动总长度 71 | * @return 72 | */ 73 | public int getTotalVerticalScrollRange() { 74 | return this.computeVerticalScrollRange(); 75 | } 76 | 77 | 78 | @Override 79 | protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) { 80 | return 0; // 禁止ScrollView在子控件的布局改变时自动滚动 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/mvp/ABBasePresenter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.mvp; 2 | 3 | import com.wangjie.androidbucket.application.HttpApplicationController; 4 | import com.wangjie.androidbucket.log.Logger; 5 | import com.wangjie.androidbucket.services.CancelableTask; 6 | import com.wangjie.androidbucket.services.network.HippoRequest; 7 | import com.wangjie.androidbucket.thread.Runtask; 8 | import com.wangjie.androidbucket.thread.ThreadPool; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Iterator; 12 | import java.util.List; 13 | 14 | /** 15 | * Author: wangjie 16 | * Email: tiantian.china.2@gmail.com 17 | * Date: 7/17/14. 18 | *

19 | * MVP的Presenter层,作为沟通View和Model的桥梁,它从Model层检索数据后,返回给View层,它也可以决定与View层的交互操作。 20 | * 它包含一个View层的引用和一个Model层的引用 21 | */ 22 | public class ABBasePresenter implements ABBaseTaskManager { 23 | 24 | private static final String TAG = ABBasePresenter.class.getSimpleName(); 25 | 26 | protected V viewer; 27 | protected I interactor; 28 | 29 | protected ABBasePresenter() { 30 | cancelableTaskList = new ArrayList<>(); 31 | } 32 | 33 | private List cancelableTaskList; 34 | 35 | @Override 36 | public void addCancelableTask(CancelableTask cancelableTask) { 37 | cancelableTaskList.add(cancelableTask); 38 | } 39 | 40 | @Override 41 | public void removeCancelableTask(CancelableTask cancelableTask) { 42 | Logger.i(TAG, "removeCancelableTask: " + cancelableTask); 43 | cancelableTaskList.remove(cancelableTask); 44 | } 45 | 46 | @Override 47 | public void closeAllTask() { 48 | for (CancelableTask task : cancelableTaskList) { 49 | Logger.i(TAG, "closeAllTask: " + task); 50 | task.cancel(true); 51 | } 52 | cancelableTaskList.clear(); 53 | } 54 | 55 | public void goRuntask(Runtask runtask) { 56 | addCancelableTask(runtask); 57 | ThreadPool.go(runtask); 58 | } 59 | 60 | public void addHttpRequest(HippoRequest request) { 61 | addCancelableTask(request); 62 | HttpApplicationController.getInstance().addToRequestQueue(request); 63 | } 64 | 65 | public V getViewer() { 66 | return viewer; 67 | } 68 | 69 | public void setViewer(V viewer) { 70 | this.viewer = viewer; 71 | } 72 | 73 | public I getInteractor() { 74 | return interactor; 75 | } 76 | 77 | public void setInteractor(I interactor) { 78 | this.interactor = interactor; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/recyclerview/layoutmanager/ABaseLinearLayoutManager.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.recyclerview.layoutmanager; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.LinearLayoutManager; 5 | import android.support.v7.widget.RecyclerView; 6 | import com.wangjie.androidbucket.support.recyclerview.listener.OnRecyclerViewScrollLocationListener; 7 | 8 | /** 9 | * Author: wangjie 10 | * Email: tiantian.china.2@gmail.com 11 | * Date: 1/19/15. 12 | */ 13 | public class ABaseLinearLayoutManager extends LinearLayoutManager implements RecyclerViewScrollManager.OnScrollManagerLocation { 14 | private static final String TAG = ABaseLinearLayoutManager.class.getSimpleName(); 15 | 16 | private RecyclerViewScrollManager recyclerViewScrollManager; 17 | 18 | public void setOnRecyclerViewScrollLocationListener(RecyclerView recyclerView, OnRecyclerViewScrollLocationListener onRecyclerViewScrollLocationListener) { 19 | ensureRecyclerViewScrollManager(); 20 | recyclerViewScrollManager.setOnRecyclerViewScrollLocationListener(onRecyclerViewScrollLocationListener); 21 | recyclerViewScrollManager.setOnScrollManagerLocation(this); 22 | recyclerViewScrollManager.registerScrollListener(recyclerView); 23 | } 24 | 25 | public ABaseLinearLayoutManager(Context context) { 26 | super(context); 27 | } 28 | 29 | public ABaseLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { 30 | super(context, orientation, reverseLayout); 31 | } 32 | 33 | public boolean isScrolling() { 34 | if (null != recyclerViewScrollManager) { 35 | return recyclerViewScrollManager.isScrolling(); 36 | } 37 | return false; 38 | } 39 | 40 | public RecyclerViewScrollManager getRecyclerViewScrollManager() { 41 | ensureRecyclerViewScrollManager(); 42 | return recyclerViewScrollManager; 43 | } 44 | private void ensureRecyclerViewScrollManager(){ 45 | if (null == recyclerViewScrollManager) { 46 | recyclerViewScrollManager = new RecyclerViewScrollManager(); 47 | } 48 | } 49 | 50 | @Override 51 | public boolean isTop(RecyclerView recyclerView) { 52 | return 0 == findFirstVisibleItemPosition(); 53 | } 54 | 55 | @Override 56 | public boolean isBottom(RecyclerView recyclerView) { 57 | int lastVisiblePosition = findLastCompletelyVisibleItemPosition(); 58 | int lastPosition = recyclerView.getAdapter().getItemCount() - 1; 59 | return lastVisiblePosition == lastPosition; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/pinnedexpandablelistview/PinnedBaseExpandableAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.pinnedexpandablelistview; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.widget.BaseExpandableListAdapter; 6 | 7 | import java.util.HashMap; 8 | 9 | /** 10 | * Author: wangjie 11 | * Email: tiantian.china.2@gmail.com 12 | * Date: 8/20/14. 13 | */ 14 | public abstract class PinnedBaseExpandableAdapter extends BaseExpandableListAdapter implements PinnedExpandableListView.PinnedExpandableHeaderAdapter { 15 | public static final String TAG = PinnedBaseExpandableAdapter.class.getSimpleName(); 16 | protected Context context; 17 | protected PinnedExpandableListView pinnedElv; 18 | 19 | public PinnedBaseExpandableAdapter(Context context, PinnedExpandableListView pinnedElv) { 20 | this.context = context; 21 | this.pinnedElv = pinnedElv; 22 | View headView = getHeaderView(); 23 | if(null != headView){ 24 | this.pinnedElv.setHeaderView(headView); 25 | } 26 | } 27 | 28 | /** 29 | * 头部浮动的view 30 | * @return 31 | */ 32 | public abstract View getHeaderView(); 33 | 34 | @Override 35 | public boolean hasStableIds() { 36 | return true; 37 | } 38 | 39 | 40 | @Override 41 | public boolean isChildSelectable(int groupPosition, int childPosition) { 42 | return true; 43 | } 44 | 45 | 46 | 47 | /**************** implements PinnedExpandableListView.PinnedExpandableHeaderAdapter impl *********************/ 48 | 49 | @Override 50 | public int getPinnedExpandableHeaderState(int groupPosition, int childPosition) { 51 | final int childCount = getChildrenCount(groupPosition); 52 | if (childPosition == childCount - 1) { 53 | return PINNED_HEADER_PUSHED_UP; 54 | } else if (childPosition == -1 && !pinnedElv.isGroupExpanded(groupPosition)) { 55 | return PINNED_HEADER_GONE; 56 | } else { 57 | return PINNED_HEADER_VISIBLE; 58 | } 59 | } 60 | 61 | 62 | private HashMap groupStatusMap = new HashMap(); 63 | @Override 64 | public void setGroupClickStatus(int groupPosition, int status) { 65 | groupStatusMap.put(groupPosition, status); 66 | } 67 | 68 | @Override 69 | public int getGroupClickStatus(int groupPosition) { 70 | if (groupStatusMap.containsKey(groupPosition)) { 71 | return groupStatusMap.get(groupPosition); 72 | } else { 73 | return 0; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/recyclerview/layoutmanager/ABaseGridLayoutManager.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.recyclerview.layoutmanager; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.GridLayoutManager; 5 | import android.support.v7.widget.RecyclerView; 6 | import com.wangjie.androidbucket.support.recyclerview.listener.OnRecyclerViewScrollLocationListener; 7 | 8 | /** 9 | * Author: wangjie 10 | * Email: tiantian.china.2@gmail.com 11 | * Date: 1/19/15. 12 | */ 13 | public class ABaseGridLayoutManager extends GridLayoutManager implements RecyclerViewScrollManager.OnScrollManagerLocation { 14 | private static final String TAG = ABaseGridLayoutManager.class.getSimpleName(); 15 | 16 | private RecyclerViewScrollManager recyclerViewScrollManager; 17 | 18 | public void setOnRecyclerViewScrollListener(RecyclerView recyclerView, OnRecyclerViewScrollLocationListener onRecyclerViewScrollLocationListener) { 19 | ensureRecyclerViewScrollManager(); 20 | recyclerViewScrollManager.setOnRecyclerViewScrollLocationListener(onRecyclerViewScrollLocationListener); 21 | recyclerViewScrollManager.setOnScrollManagerLocation(this); 22 | recyclerViewScrollManager.registerScrollListener(recyclerView); 23 | } 24 | 25 | public ABaseGridLayoutManager(Context context, int spanCount) { 26 | super(context, spanCount); 27 | } 28 | 29 | public ABaseGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) { 30 | super(context, spanCount, orientation, reverseLayout); 31 | } 32 | 33 | public boolean isScrolling() { 34 | if (null != recyclerViewScrollManager) { 35 | return recyclerViewScrollManager.isScrolling(); 36 | } 37 | return false; 38 | } 39 | 40 | public RecyclerViewScrollManager getRecyclerViewScrollManager() { 41 | ensureRecyclerViewScrollManager(); 42 | return recyclerViewScrollManager; 43 | } 44 | 45 | private void ensureRecyclerViewScrollManager() { 46 | if (null == recyclerViewScrollManager) { 47 | recyclerViewScrollManager = new RecyclerViewScrollManager(); 48 | } 49 | } 50 | 51 | @Override 52 | public boolean isTop(RecyclerView recyclerView) { 53 | return 0 == findFirstVisibleItemPosition(); 54 | } 55 | 56 | @Override 57 | public boolean isBottom(RecyclerView recyclerView) { 58 | int lastVisiblePosition = findLastCompletelyVisibleItemPosition(); 59 | int lastPosition = recyclerView.getAdapter().getItemCount() - 1; 60 | return lastVisiblePosition == lastPosition; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/recyclerview/layoutmanager/ABaseStaggeredGridLayoutManager.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.recyclerview.layoutmanager; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.support.v7.widget.StaggeredGridLayoutManager; 5 | import com.wangjie.androidbucket.support.recyclerview.listener.OnRecyclerViewScrollLocationListener; 6 | import com.wangjie.androidbucket.utils.ABTextUtil; 7 | 8 | import java.util.Arrays; 9 | 10 | /** 11 | * Author: wangjie 12 | * Email: tiantian.china.2@gmail.com 13 | * Date: 1/19/15. 14 | */ 15 | public class ABaseStaggeredGridLayoutManager extends StaggeredGridLayoutManager implements RecyclerViewScrollManager.OnScrollManagerLocation { 16 | private static final String TAG = ABaseStaggeredGridLayoutManager.class.getSimpleName(); 17 | 18 | private RecyclerViewScrollManager recyclerViewScrollManager; 19 | 20 | public void setOnRecyclerViewScrollListener(RecyclerView recyclerView, OnRecyclerViewScrollLocationListener onRecyclerViewScrollLocationListener) { 21 | ensureRecyclerViewScrollManager(); 22 | recyclerViewScrollManager.setOnRecyclerViewScrollLocationListener(onRecyclerViewScrollLocationListener); 23 | recyclerViewScrollManager.setOnScrollManagerLocation(this); 24 | recyclerViewScrollManager.registerScrollListener(recyclerView); 25 | } 26 | 27 | public ABaseStaggeredGridLayoutManager(int spanCount, int orientation) { 28 | super(spanCount, orientation); 29 | } 30 | 31 | public boolean isScrolling() { 32 | if (null != recyclerViewScrollManager) { 33 | return recyclerViewScrollManager.isScrolling(); 34 | } 35 | return false; 36 | } 37 | 38 | public RecyclerViewScrollManager getRecyclerViewScrollManager() { 39 | ensureRecyclerViewScrollManager(); 40 | return recyclerViewScrollManager; 41 | } 42 | private void ensureRecyclerViewScrollManager(){ 43 | if (null == recyclerViewScrollManager) { 44 | recyclerViewScrollManager = new RecyclerViewScrollManager(); 45 | } 46 | } 47 | 48 | 49 | @Override 50 | public boolean isTop(RecyclerView recyclerView) { 51 | int[] into = findFirstVisibleItemPositions(null); 52 | return !ABTextUtil.isEmpty(into) && 0 == into[0]; 53 | } 54 | 55 | @Override 56 | public boolean isBottom(RecyclerView recyclerView) { 57 | int into[] = findLastCompletelyVisibleItemPositions(null); 58 | int lastPosition = recyclerView.getAdapter().getItemCount() - 1; 59 | Arrays.sort(into); 60 | return !ABTextUtil.isEmpty(into) && lastPosition == into[into.length - 1]; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | AndroidBucket 2 | ============= 3 | 4 | ###Android开发常用整理(不断扩充中)
包含各种工具类、线程池、日志、自定义的控件、程序崩溃捕捉处理、默认的Application配置、常用的Adapter等 5 | 6 | ###注意:
7 | > 如果需要使用FragmentTabAdapter,则需要android-support-v4.jar的支持(以兼容低版本) 8 | 9 | ###使用方法
10 | clone代码,并在项目中引入AndroidBucket。 11 | 12 | ###Gradle([Check newest version](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22AndroidBucket%22)) 13 | compile 'com.github.wangjiegulu:AndroidBucket:x.x.x' 14 | ###Maven([Check newest version](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22AndroidBucket%22)) 15 | 16 | com.github.wangjiegulu 17 | AndroidBucket 18 | x.x.x 19 | aar 20 | 21 | 22 | ###线程池、日志、程序崩溃捕捉处理等配置方法
23 | 新建MyApplication,继承ABApplication,根据需要实现里面的方法 24 | initThreadPool(); // 初始化线程池 25 | initLogger(); // 初始化日志工具 26 | initImageLoader(); // 初始化图片加载器 27 | initCrashHandler(); // 初始化程序崩溃捕捉处理 28 | 注意:除了图片加载器外,其他的初始化操作ABApplication都提供了默认的初始化支持。 29 | 图片加载器推荐使用[ImageLoaderSample](https://github.com/wangjiegulu/ImageLoaderSample)项目。 30 | 31 | MyApplication: 32 | public class ABApplication extends Application{ 33 | @Override 34 | public void onCreate() { 35 | super.onCreate(); 36 | } 37 | 38 | /** 39 | * 初始化线程池 40 | */ 41 | protected void initThreadPool(){ 42 | ThreadPool.initThreadPool(7); 43 | } 44 | 45 | /** 46 | * 初始化日志 47 | */ 48 | protected void initLogger(){ 49 | Logger.initLogger(null); 50 | } 51 | 52 | /** 53 | * 初始化图片加载器 54 | */ 55 | protected void initImageLoader(){ 56 | 57 | } 58 | 59 | /** 60 | * 初始化程序崩溃捕捉处理 61 | */ 62 | protected void initCrashHandler(){ 63 | ABCrashHandler.init(getApplicationContext()); 64 | } 65 | 66 | } 67 | 68 | License 69 | ======= 70 | 71 | Copyright 2013 Wang Jie 72 | 73 | Licensed under the Apache License, Version 2.0 (the "License"); 74 | you may not use this file except in compliance with the License. 75 | You may obtain a copy of the License at 76 | 77 | http://www.apache.org/licenses/LICENSE-2.0 78 | 79 | Unless required by applicable law or agreed to in writing, software 80 | distributed under the License is distributed on an "AS IS" BASIS, 81 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 82 | See the License for the specific language governing blacklist and 83 | limitations under the License. 84 | 85 | 86 | 87 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-AndroidBucket-brightgreen.svg?style=flat)](http://android-arsenal.com/details/1/1579) 88 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/HippoRequestQueue.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network; 2 | 3 | import com.wangjie.androidbucket.log.Logger; 4 | 5 | import java.util.concurrent.PriorityBlockingQueue; 6 | import java.util.concurrent.atomic.AtomicInteger; 7 | 8 | /** 9 | * @author Hubert He 10 | * @version V1.0 11 | * @Description 12 | * @Createdate 14-9-24 14:02 13 | */ 14 | public class HippoRequestQueue { 15 | 16 | private static final String TAG = HippoRequestQueue.class.getName(); 17 | 18 | private AtomicInteger seqGenerator = new AtomicInteger(); 19 | 20 | /** 21 | * 正在等待队列 22 | */ 23 | private PriorityBlockingQueue waitingQueue; 24 | 25 | /** 26 | * 网络访问类 27 | */ 28 | private HippoNetworkDispatcher[] hippoNetworkDispatchers; 29 | 30 | /** 31 | * 默认最大线程数量 32 | */ 33 | private static final int MAX_THREAD_POOL_SIZE = 10; 34 | 35 | /** 36 | * 线程池大小 37 | */ 38 | private final int threadPoolSize; 39 | 40 | /** 41 | * 网络请求执行 42 | */ 43 | private Network network; 44 | 45 | public HippoRequestQueue(Network network) { 46 | this(network, MAX_THREAD_POOL_SIZE); 47 | } 48 | 49 | /** 50 | * 构造方法,初始化Queue 51 | */ 52 | public HippoRequestQueue(Network network, int threadPoolSize) { 53 | waitingQueue = new PriorityBlockingQueue<>(); 54 | this.threadPoolSize = threadPoolSize; 55 | this.network = network; 56 | start(); 57 | } 58 | 59 | /** 60 | * @param request 61 | * @return 62 | */ 63 | public void add(HippoRequest request) { 64 | request.seq = seqGenerator.getAndIncrement(); 65 | waitingQueue.add(request); 66 | } 67 | 68 | /** 69 | * @return 70 | */ 71 | public void stop() { 72 | if (hippoNetworkDispatchers != null) { 73 | for (HippoNetworkDispatcher dispatcher : hippoNetworkDispatchers) { 74 | dispatcher.quit(); 75 | } 76 | } 77 | } 78 | 79 | public void start() { 80 | stop(); 81 | try { 82 | hippoNetworkDispatchers = new HippoNetworkDispatcher[threadPoolSize]; 83 | for (int i = 0; i < hippoNetworkDispatchers.length; i++) { 84 | hippoNetworkDispatchers[i] = new HippoNetworkDispatcher(waitingQueue, network); 85 | hippoNetworkDispatchers[i].start(); 86 | } 87 | } catch (Exception e) { 88 | Logger.e(TAG, e); 89 | } 90 | } 91 | 92 | public static HippoRequestQueue newHippoRequestQueue(Network network) { 93 | return new HippoRequestQueue(network); 94 | } 95 | 96 | public static HippoRequestQueue newHippoRequestQueue(Network network, 97 | int threadPoolSize) { 98 | return new HippoRequestQueue(network, threadPoolSize); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/security/des3/Des3.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.security.des3; 2 | 3 | import javax.crypto.Cipher; 4 | import javax.crypto.SecretKeyFactory; 5 | import javax.crypto.spec.DESedeKeySpec; 6 | import javax.crypto.spec.IvParameterSpec; 7 | import java.security.Key; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * Author: wangjie email:tiantian.china.2@gmail.com 12 | * Date: 14-4-4 13 | * Time: 上午10:44 14 | */ 15 | public class Des3 { 16 | // 默认密钥 17 | // private final static String secretKey = "liuyunqiang@lx100$#365#$"; 18 | private final static String secretKey = "wangjie@x19900915$#365#$"; 19 | // 默认向量 20 | private final static String iv = "01234567"; 21 | // 加解密统一使用的编码方式 22 | private final static String encoding = "utf-8"; 23 | 24 | /** 25 | * 3DES加密(使用默认密钥和默认向量) 26 | * 27 | * @param plainText 普通文本 28 | * @return 29 | * @throws Exception 30 | */ 31 | public static String encode(String plainText) throws Exception { 32 | return encode(plainText, secretKey, iv); 33 | } 34 | 35 | /** 36 | * 3DES加密(指定密钥和指定向量) 37 | * @param plainText 38 | * @param sKey 39 | * @param iv 40 | * @return 41 | * @throws Exception 42 | */ 43 | public static String encode(String plainText, String sKey, String iv) throws Exception { 44 | DESedeKeySpec spec = new DESedeKeySpec(sKey.getBytes()); 45 | SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); 46 | Key deskey = keyfactory.generateSecret(spec); 47 | 48 | Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding"); 49 | IvParameterSpec ips = new IvParameterSpec(iv.getBytes()); 50 | cipher.init(Cipher.ENCRYPT_MODE, deskey, ips); 51 | byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding)); 52 | return Base64.encode(encryptData); 53 | } 54 | 55 | /** 56 | * 3DES解密(使用默认密钥和默认向量) 57 | * 58 | * @param encryptText 加密文本 59 | * @return 60 | * @throws Exception 61 | */ 62 | public static String decode(String encryptText) throws Exception { 63 | return decode(encryptText, secretKey, iv); 64 | } 65 | /** 66 | * 3DES解密(指定密钥和指定向量) 67 | * 68 | * @param encryptText 加密文本 69 | * @param sKey 70 | * @param iv 71 | * @return 72 | * @throws Exception 73 | */ 74 | public static String decode(String encryptText, String sKey, String iv) throws Exception { 75 | DESedeKeySpec spec = new DESedeKeySpec(sKey.getBytes()); 76 | SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); 77 | Key deskey = keyfactory.generateSecret(spec); 78 | Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding"); 79 | IvParameterSpec ips = new IvParameterSpec(iv.getBytes()); 80 | cipher.init(Cipher.DECRYPT_MODE, deskey, ips); 81 | 82 | byte[] decryptData = cipher.doFinal(Base64.decode(encryptText)); 83 | 84 | return new String(decryptData, encoding); 85 | } 86 | 87 | 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/core/collecion/HashList.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.core.collecion; 2 | 3 | import java.util.*; 4 | 5 | /*** 6 | * 键值对索引排序的工具类 HashMap简单排序的一种实现 7 | * 8 | * @param 9 | * @param 10 | */ 11 | public class HashList { 12 | 13 | /** 14 | * 键值集合{A, B, C...} 15 | * */ 16 | private List keyArr = new ArrayList(); 17 | /** 18 | * 键值对映射{A:add..., B:ball..., ...} 19 | */ 20 | private HashMap> map = new HashMap>(); 21 | /** 22 | * 键值分类 23 | */ 24 | private KeySort keySort; 25 | 26 | public HashList(KeySort keySort) { 27 | this.keySort = keySort; 28 | } 29 | 30 | /** 31 | * 根据value值返回key 32 | * */ 33 | 34 | public K getKey(V v) { 35 | return keySort.getKey(v); 36 | } 37 | 38 | /** 键值对排序 */ 39 | public void sortKeyComparator(Comparator comparator) { 40 | Collections.sort(keyArr, comparator); 41 | } 42 | 43 | /** 根据索引返回键值 */ 44 | public K getKeyIndex(int key) { 45 | return keyArr.get(key); 46 | } 47 | 48 | /** 根据索引返回键值对 */ 49 | public List getValueListIndex(int key) { 50 | return map.get(getKeyIndex(key)); 51 | } 52 | 53 | public V getValueIndex(int key, int value) { 54 | return getValueListIndex(key).get(value); 55 | 56 | } 57 | 58 | public int size() { 59 | return keyArr.size(); 60 | } 61 | 62 | public void clear() { 63 | for (Iterator it = map.keySet().iterator(); it.hasNext(); map.remove(it.next())); 64 | } 65 | 66 | public boolean contains(Object object) { 67 | return false; 68 | } 69 | 70 | public boolean isEmpty() { 71 | return false; 72 | } 73 | 74 | public Object remove(int location) { 75 | return null; 76 | } 77 | 78 | public boolean remove(Object object) { 79 | return false; 80 | } 81 | 82 | public boolean removeAll(Collection arg0) { 83 | return false; 84 | } 85 | 86 | public boolean retainAll(Collection arg0) { 87 | return false; 88 | } 89 | 90 | public Object set(int location, Object object) { 91 | return keyArr.set(location, (K) object); 92 | } 93 | 94 | public List subList(int start, int end) { 95 | return keyArr.subList(start, end); 96 | } 97 | 98 | public Object[] toArray() { 99 | return keyArr.toArray(); 100 | } 101 | 102 | public Object[] toArray(Object[] array) { 103 | return keyArr.toArray(array); 104 | } 105 | 106 | public boolean add(V v) { 107 | K key = getKey(v); 108 | if (!map.containsKey(key)) { 109 | List list = new ArrayList(); 110 | list.add(v); 111 | keyArr.add(key); 112 | map.put(key, list); 113 | } else { 114 | map.get(key).add(v); 115 | } 116 | return false; 117 | } 118 | 119 | public int indexOfKey(K k){ 120 | return keyArr.indexOf(k); 121 | } 122 | 123 | } -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/horizontialmenu/HorizontialMenu.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.horizontialmenu; 2 | 3 | import android.content.Context; 4 | import android.graphics.Color; 5 | import android.graphics.drawable.ColorDrawable; 6 | import android.graphics.drawable.Drawable; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.PopupWindow; 11 | import android.widget.TextView; 12 | import com.wangjie.androidbucket.R; 13 | import com.wangjie.androidbucket.utils.ABIOUtil; 14 | import com.wangjie.androidbucket.utils.ABTextUtil; 15 | 16 | /** 17 | * Created by wangjie on 14-5-5. 18 | */ 19 | public class HorizontialMenu{ 20 | 21 | private Context context; 22 | private PopupWindow popMenu; // 菜单控件 23 | private Drawable background; 24 | private String[] items; 25 | private int itemSize; 26 | private OnHoriMenuItemListener listener; 27 | 28 | 29 | 30 | public static PopupWindow createHoriMenu(Context context, Drawable background, String[] items, OnHoriMenuItemListener listener){ 31 | HorizontialMenu menu = new HorizontialMenu(context, background, items, listener); 32 | return menu.popMenu; 33 | } 34 | 35 | 36 | public HorizontialMenu(Context context, Drawable background, String[] items, OnHoriMenuItemListener listener) { 37 | this.context = context; 38 | this.items = items; 39 | this.listener = listener; 40 | this.background = background; 41 | itemSize = null == items ? 0 : items.length; 42 | initMenu(); 43 | 44 | } 45 | 46 | private void initMenu(){ 47 | View contentView = LayoutInflater.from(context).inflate(R.layout.ab_horizontial_edit_menu, null); 48 | if(itemSize <= 0 || null == contentView){ 49 | return; 50 | } 51 | ViewGroup itemsVg = (ViewGroup) contentView.findViewById(R.id.ab_horizontial_edit_menu_items_view); 52 | 53 | for(int i = 0; i < itemSize; i++){ 54 | TextView im = new TextView(context); 55 | im.setTextColor(Color.WHITE); 56 | im.setText(items[i]); 57 | im.setTextSize(15); 58 | im.setPadding(ABTextUtil.dip2px(context, 8), ABTextUtil.dip2px(context, 3), ABTextUtil.dip2px(context, 8), ABTextUtil.dip2px(context, 3)); 59 | if(null != listener){ 60 | final int j = i; 61 | im.setOnClickListener(new View.OnClickListener() { 62 | @Override 63 | public void onClick(View view) { 64 | listener.onItemClick(view, j); 65 | } 66 | }); 67 | } 68 | 69 | itemsVg.addView(im); 70 | } 71 | 72 | 73 | popMenu = new PopupWindow(contentView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 74 | popMenu.setBackgroundDrawable(null == background ? new ColorDrawable(Color.parseColor("#cc000000")) : background); 75 | popMenu.setAnimationStyle(android.R.style.Animation_Dialog); 76 | popMenu.setFocusable(true); 77 | 78 | } 79 | 80 | 81 | 82 | 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/cardview/CardViewEclairMr1.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.cardview; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Paint; 6 | import android.graphics.RectF; 7 | 8 | /** 9 | * Author: wangjie 10 | * Email: tiantian.china.2@gmail.com 11 | * Date: 12/15/14. 12 | */ 13 | class CardViewEclairMr1 implements CardViewImpl { 14 | 15 | final RectF sCornerRect = new RectF(); 16 | 17 | @Override 18 | public void initStatic() { 19 | // Draws a round rect using 7 draw operations. This is faster than using 20 | // canvas.drawRoundRect before JBMR1 because API 11-16 used alpha mask textures to draw 21 | // shapes. 22 | RoundRectDrawableWithShadow.sRoundRectHelper = new RoundRectDrawableWithShadow.RoundRectHelper() { 23 | 24 | @Override 25 | public void drawRoundRect(Canvas canvas, RectF bounds, float cornerRadius, Paint paint) { 26 | final float twoRadius = cornerRadius * 2; 27 | final float innerWidth = bounds.width() - twoRadius; 28 | final float innerHeight = bounds.height() - twoRadius; 29 | sCornerRect.set(bounds.left, bounds.top, bounds.left + (cornerRadius * 2), bounds.top 30 | + (cornerRadius * 2)); 31 | 32 | canvas.drawArc(sCornerRect, 180, 90, true, paint); 33 | sCornerRect.offset(innerWidth, 0); 34 | canvas.drawArc(sCornerRect, 270, 90, true, paint); 35 | sCornerRect.offset(0, innerHeight); 36 | canvas.drawArc(sCornerRect, 0, 90, true, paint); 37 | sCornerRect.offset(-innerWidth, 0); 38 | canvas.drawArc(sCornerRect, 90, 90, true, paint); 39 | 40 | // draw top and bottom pieces 41 | canvas.drawRect(bounds.left + cornerRadius, bounds.top, bounds.right - cornerRadius, bounds.top 42 | + cornerRadius, paint); 43 | canvas.drawRect(bounds.left + cornerRadius, bounds.bottom - cornerRadius, bounds.right - cornerRadius, 44 | bounds.bottom, paint); 45 | 46 | // center 47 | canvas.drawRect(bounds.left, bounds.top + cornerRadius, bounds.right, bounds.bottom - cornerRadius, 48 | paint); 49 | } 50 | }; 51 | } 52 | 53 | @Override 54 | public void initialize(CardViewDelegate cardView, Context context, int backgroundColor, float radius, CardShadow cardShadow) { 55 | RoundRectDrawableWithShadow background = new RoundRectDrawableWithShadow(context.getResources(), 56 | backgroundColor, radius, cardShadow); 57 | cardView.setBackgroundDrawable(background); 58 | } 59 | 60 | @Override 61 | public void setRadius(CardViewDelegate cardView, float radius) { 62 | ((RoundRectDrawableWithShadow)cardView.getBackground()).setCornerRadius(radius); 63 | } 64 | 65 | @Override 66 | public float getRadius(CardViewDelegate cardView) { 67 | return ((RoundRectDrawableWithShadow)cardView.getBackground()).getCornerRadius(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 | 28 | 29 | 35 | 36 | 37 | 54 | 55 | 56 | 57 | 58 | 59 | 67 | 70 | 73 | 74 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/typeadapter/expand/BaseExpandTypeAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter.typeadapter.expand; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.ExpandableListView; 8 | import com.wangjie.androidbucket.R; 9 | import com.wangjie.androidbucket.adapter.ABaseExpandableListAdapter; 10 | 11 | /** 12 | * Author: wangjie 13 | * Email: tiantian.china.2@gmail.com 14 | * Date: 12/19/14. 15 | */ 16 | public abstract class BaseExpandTypeAdapter extends ABaseExpandableListAdapter { 17 | protected BaseExpandTypeAdapter(ExpandableListView listView) { 18 | super(listView); 19 | } 20 | 21 | @TargetApi(Build.VERSION_CODES.DONUT) 22 | @Override 23 | public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { 24 | ExpandGroupAdapterTypeRender typeRender; 25 | if (null == convertView) { 26 | typeRender = getGroupAdapterTypeRender(groupPosition); 27 | convertView = typeRender.getConvertView(); 28 | convertView.setTag(R.id.ab__id_adapter_item_type_render, typeRender); 29 | typeRender.fitEvents(); 30 | } else { 31 | typeRender = (ExpandGroupAdapterTypeRender) convertView.getTag(R.id.ab__id_adapter_item_type_render); 32 | } 33 | convertView.setTag(R.id.ab__id_adapter_group_position, groupPosition); 34 | 35 | if (null != typeRender) { 36 | typeRender.fitDatas(groupPosition); 37 | } 38 | 39 | return convertView; 40 | } 41 | 42 | @TargetApi(Build.VERSION_CODES.DONUT) 43 | @Override 44 | public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { 45 | ExpandChildAdapterTypeRender typeRender; 46 | if (null == convertView) { 47 | typeRender = getChildAdapterTypeRender(groupPosition, childPosition); 48 | convertView = typeRender.getConvertView(); 49 | convertView.setTag(R.id.ab__id_adapter_item_type_render, typeRender); 50 | typeRender.fitEvents(); 51 | } else { 52 | typeRender = (ExpandChildAdapterTypeRender) convertView.getTag(R.id.ab__id_adapter_item_type_render); 53 | } 54 | convertView.setTag(R.id.ab__id_adapter_group_position, groupPosition); 55 | convertView.setTag(R.id.ab__id_adapter_child_position, childPosition); 56 | 57 | if (null != typeRender) { 58 | typeRender.fitDatas(groupPosition, childPosition); 59 | } 60 | 61 | return convertView; 62 | } 63 | 64 | /** 65 | * 根据指定position的item获取对应的type,然后通过type实例化一个AdapterTypeRender的实现 66 | * 67 | * @param groupPosition 68 | * @return 69 | */ 70 | public abstract ExpandGroupAdapterTypeRender getGroupAdapterTypeRender(int groupPosition); 71 | 72 | /** 73 | * 根据指定position的item获取对应的type,然后通过type实例化一个AdapterTypeRender的实现 74 | * 75 | * @param groupPosition 76 | * @param childPosition 77 | * @return 78 | */ 79 | public abstract ExpandChildAdapterTypeRender getChildAdapterTypeRender(int groupPosition, int childPosition); 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/ABaseAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter; 2 | 3 | import android.widget.*; 4 | import com.wangjie.androidbucket.adapter.listener.OnAdapterScrollListener; 5 | import com.wangjie.androidbucket.log.Logger; 6 | 7 | /** 8 | * Author: wangjie 9 | * Email: tiantian.china.2@gmail.com 10 | * Date: 12/3/14. 11 | */ 12 | public abstract class ABaseAdapter extends BaseAdapter implements AbsListView.OnScrollListener { 13 | private static final String TAG = ABaseAdapter.class.getSimpleName(); 14 | private OnAdapterScrollListener onAdapterScrollListener; 15 | /** 16 | * 当前listview是否属于滚动状态 17 | */ 18 | private boolean isScrolling; 19 | 20 | public boolean isScrolling() { 21 | return isScrolling; 22 | } 23 | 24 | public void setOnAdapterScrollListener(OnAdapterScrollListener onAdapterScrollListener) { 25 | this.onAdapterScrollListener = onAdapterScrollListener; 26 | } 27 | 28 | protected ABaseAdapter(AbsListView listView) { 29 | listView.setOnScrollListener(this); 30 | } 31 | 32 | @Override 33 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 34 | if (null != onAdapterScrollListener) { 35 | onAdapterScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); 36 | } 37 | } 38 | 39 | @Override 40 | public void onScrollStateChanged(AbsListView view, int scrollState) { 41 | if (null != onAdapterScrollListener) { 42 | onAdapterScrollListener.onScrollStateChanged(view, scrollState); 43 | } 44 | 45 | // 设置是否滚动的状态 46 | if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) { // 不滚动状态 47 | isScrolling = false; 48 | this.notifyDataSetChanged(); 49 | 50 | // 滚动到顶部和滚动到低部的回调 51 | if (null != onAdapterScrollListener) { 52 | checkTopWhenScrollIdle(view); 53 | checkBottomWhenScrollIdle(view); 54 | } 55 | } else { 56 | isScrolling = true; 57 | } 58 | 59 | } 60 | 61 | /** 62 | * 监测是否滚动到顶部 63 | * 64 | * @param view 65 | */ 66 | private void checkTopWhenScrollIdle(final AbsListView view) { 67 | if (view.getFirstVisiblePosition() <= 0) { 68 | if (null != onAdapterScrollListener) { 69 | view.post(new Runnable() { 70 | @Override 71 | public void run() { 72 | onAdapterScrollListener.onTopWhenScrollIdle(view); 73 | } 74 | }); 75 | } 76 | } 77 | } 78 | 79 | /** 80 | * 监测是否滚动到底部 81 | * 82 | * @param view 83 | */ 84 | private void checkBottomWhenScrollIdle(final AbsListView view) { 85 | if (view.getLastVisiblePosition() >= (view.getCount() - 1)) { 86 | if (null != onAdapterScrollListener) { 87 | view.post(new Runnable() { 88 | @Override 89 | public void run() { 90 | onAdapterScrollListener.onBottomWhenScrollIdle(view); 91 | } 92 | }); 93 | } 94 | } 95 | } 96 | 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/system/appinfo/ABAppInfo.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.system.appinfo; 2 | 3 | import android.content.Context; 4 | import android.os.Build; 5 | import com.wangjie.androidbucket.utils.ABAppUtil; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * Created by zoe on 15/1/6. 11 | */ 12 | public class ABAppInfo implements Serializable { 13 | /** 14 | * deviceId <设备ID,可以去IMEI值, 只要用于确定该设备即可> 15 | */ 16 | private String deviceId; 17 | 18 | /** 19 | * appVer: 20 | */ 21 | private String appVer; 22 | 23 | /** 24 | * os: 25 | */ 26 | private String os; 27 | 28 | /** 29 | * osVer: 30 | */ 31 | private String osVer; 32 | 33 | /** 34 | * model: <手机型号> 35 | */ 36 | private String model; 37 | 38 | /** 39 | * nw: 网络状况 40 | */ 41 | private Integer nw; 42 | 43 | /** 44 | * 渠道 45 | */ 46 | private String channel; 47 | 48 | @Override 49 | public String toString() { 50 | return "AppInfo{" + 51 | "deviceId='" + deviceId + '\'' + 52 | ", appVer='" + appVer + '\'' + 53 | ", os='" + os + '\'' + 54 | ", osVer='" + osVer + '\'' + 55 | ", model='" + model + '\'' + 56 | ", nw=" + nw + 57 | ", channel='" + channel + '\'' + 58 | '}'; 59 | } 60 | 61 | public String getDeviceId() { 62 | return deviceId; 63 | } 64 | 65 | public void setDeviceId(String deviceId) { 66 | this.deviceId = deviceId; 67 | } 68 | 69 | public String getAppVer() { 70 | return appVer; 71 | } 72 | 73 | public void setAppVer(String appVer) { 74 | this.appVer = appVer; 75 | } 76 | 77 | public String getOs() { 78 | return os; 79 | } 80 | 81 | public void setOs(String os) { 82 | this.os = os; 83 | } 84 | 85 | public String getOsVer() { 86 | return osVer; 87 | } 88 | 89 | public void setOsVer(String osVer) { 90 | this.osVer = osVer; 91 | } 92 | 93 | public String getModel() { 94 | return model; 95 | } 96 | 97 | public void setModel(String model) { 98 | this.model = model; 99 | } 100 | 101 | public Integer getNw() { 102 | return nw; 103 | } 104 | 105 | public void setNw(int nw) { 106 | this.nw = nw; 107 | } 108 | 109 | public String getChannel() { 110 | return channel; 111 | } 112 | 113 | public void setChannel(String channel) { 114 | this.channel = channel; 115 | } 116 | 117 | 118 | public static ABAppInfo getCurrentDeviceAppInfo(Context context) { 119 | ABAppInfo ABAppInfo = new ABAppInfo(); 120 | ABAppInfo.setDeviceId(ABAppUtil.getDeviceIMEI(context)); 121 | ABAppInfo.setAppVer(ABAppUtil.getAppVersion()); 122 | ABAppInfo.setOs("android"); 123 | ABAppInfo.setOsVer(Build.VERSION.RELEASE); 124 | ABAppInfo.setModel(Build.MODEL); 125 | ABAppInfo.setNw(ABAppUtil.getNetWorkStatus(context)); 126 | ABAppInfo.setChannel("default"); 127 | return ABAppInfo; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/adapter/ABaseExpandableListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.adapter; 2 | 3 | import android.widget.AbsListView; 4 | import android.widget.BaseExpandableListAdapter; 5 | import android.widget.ExpandableListView; 6 | import com.wangjie.androidbucket.adapter.listener.OnAdapterScrollListener; 7 | import com.wangjie.androidbucket.log.Logger; 8 | 9 | /** 10 | * Author: wangjie 11 | * Email: tiantian.china.2@gmail.com 12 | * Date: 12/3/14. 13 | */ 14 | public abstract class ABaseExpandableListAdapter extends BaseExpandableListAdapter implements AbsListView.OnScrollListener { 15 | private static final String TAG = ABaseExpandableListAdapter.class.getSimpleName(); 16 | private OnAdapterScrollListener onAdapterScrollListener; 17 | private boolean isScrolling; 18 | 19 | public boolean isScrolling() { 20 | return isScrolling; 21 | } 22 | 23 | public void setOnAdapterScrollListener(OnAdapterScrollListener onAdapterScrollListener) { 24 | this.onAdapterScrollListener = onAdapterScrollListener; 25 | } 26 | 27 | protected ABaseExpandableListAdapter(ExpandableListView listView) { 28 | listView.setOnScrollListener(this); 29 | } 30 | 31 | @Override 32 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 33 | if (null != onAdapterScrollListener) { 34 | onAdapterScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); 35 | } 36 | } 37 | 38 | @Override 39 | public void onScrollStateChanged(AbsListView view, int scrollState) { 40 | if (null != onAdapterScrollListener) { 41 | onAdapterScrollListener.onScrollStateChanged(view, scrollState); 42 | } 43 | 44 | // 设置是否滚动的状态 45 | if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) { // 不滚动状态 46 | isScrolling = false; 47 | this.notifyDataSetChanged(); 48 | 49 | // 滚动到顶部和滚动到低部的回调 50 | if (null != onAdapterScrollListener) { 51 | checkTopWhenScrollIdle(view); 52 | checkBottomWhenScrollIdle(view); 53 | } 54 | } else { 55 | isScrolling = true; 56 | } 57 | 58 | } 59 | 60 | /** 61 | * 监测是否滚动到顶部 62 | * 63 | * @param view 64 | */ 65 | private void checkTopWhenScrollIdle(final AbsListView view) { 66 | if (view.getFirstVisiblePosition() <= 0) { 67 | if (null != onAdapterScrollListener) { 68 | view.post(new Runnable() { 69 | @Override 70 | public void run() { 71 | onAdapterScrollListener.onTopWhenScrollIdle(view); 72 | } 73 | }); 74 | } 75 | } 76 | } 77 | 78 | /** 79 | * 监测是否滚动到底部 80 | * 81 | * @param view 82 | */ 83 | private void checkBottomWhenScrollIdle(final AbsListView view) { 84 | if (view.getLastVisiblePosition() >= (view.getCount() - 1)) { 85 | if (null != onAdapterScrollListener) { 86 | view.post(new Runnable() { 87 | @Override 88 | public void run() { 89 | onAdapterScrollListener.onBottomWhenScrollIdle(view); 90 | } 91 | }); 92 | } 93 | } 94 | } 95 | 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/toolbox/PoolingByteArrayOutputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.wangjie.androidbucket.services.network.toolbox; 18 | 19 | import java.io.ByteArrayOutputStream; 20 | import java.io.IOException; 21 | 22 | /** 23 | * A variation of {@link java.io.ByteArrayOutputStream} that uses a pool of byte[] buffers instead 24 | * of always allocating them fresh, saving on heap churn. 25 | */ 26 | public class PoolingByteArrayOutputStream extends ByteArrayOutputStream { 27 | /** 28 | * If the {@link #PoolingByteArrayOutputStream(ByteArrayPool)} constructor is called, this is 29 | * the default size to which the underlying byte array is initialized. 30 | */ 31 | private static final int DEFAULT_SIZE = 256; 32 | 33 | private final ByteArrayPool mPool; 34 | 35 | /** 36 | * Constructs a new PoolingByteArrayOutputStream with a default size. If more bytes are written 37 | * to this instance, the underlying byte array will expand. 38 | */ 39 | public PoolingByteArrayOutputStream(ByteArrayPool pool) { 40 | this(pool, DEFAULT_SIZE); 41 | } 42 | 43 | /** 44 | * Constructs a new {@code ByteArrayOutputStream} with a default size of {@code size} bytes. If 45 | * more than {@code size} bytes are written to this instance, the underlying byte array will 46 | * expand. 47 | * 48 | * @param size initial size for the underlying byte array. The value will be pinned to a default 49 | * minimum size. 50 | */ 51 | public PoolingByteArrayOutputStream(ByteArrayPool pool, int size) { 52 | mPool = pool; 53 | buf = mPool.getBuf(Math.max(size, DEFAULT_SIZE)); 54 | } 55 | 56 | @Override 57 | public void close() throws IOException { 58 | mPool.returnBuf(buf); 59 | buf = null; 60 | super.close(); 61 | } 62 | 63 | @Override 64 | public void finalize() { 65 | mPool.returnBuf(buf); 66 | } 67 | 68 | /** 69 | * Ensures there is enough space in the buffer for the given number of additional bytes. 70 | */ 71 | private void expand(int i) { 72 | /* Can the buffer handle @i more bytes, if not expand it */ 73 | if (count + i <= buf.length) { 74 | return; 75 | } 76 | byte[] newbuf = mPool.getBuf((count + i) * 2); 77 | System.arraycopy(buf, 0, newbuf, 0, count); 78 | mPool.returnBuf(buf); 79 | buf = newbuf; 80 | } 81 | 82 | @Override 83 | public synchronized void write(byte[] buffer, int offset, int len) { 84 | expand(len); 85 | super.write(buffer, offset, len); 86 | } 87 | 88 | @Override 89 | public synchronized void write(int oneByte) { 90 | expand(1); 91 | super.write(oneByte); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/manager/BaseActivityManager.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.manager; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Author: wangjie 11 | * Email: tiantian.china.2@gmail.com 12 | * Date: 8/11/14. 13 | */ 14 | public class BaseActivityManager { 15 | 16 | private List onActivityLifeCycleListeners; 17 | 18 | public BaseActivityManager(Activity activity) { 19 | } 20 | 21 | public void registerOnActivityLifeCycleListeners(OnActivityLifeCycleListener listener) { 22 | synchronized (this) { 23 | if (onActivityLifeCycleListeners == null) { 24 | onActivityLifeCycleListeners = new ArrayList(); 25 | } 26 | 27 | if (!onActivityLifeCycleListeners.contains(listener)) { 28 | onActivityLifeCycleListeners.add(listener); 29 | } 30 | } 31 | } 32 | 33 | public void unregisterOnActivityStopListener(OnActivityLifeCycleListener listener) { 34 | synchronized (this) { 35 | if (onActivityLifeCycleListeners != null) { 36 | onActivityLifeCycleListeners.remove(listener); 37 | } 38 | } 39 | } 40 | 41 | public void dispatchActivityDestory() { 42 | List list; 43 | synchronized (this) { 44 | if (onActivityLifeCycleListeners == null) { 45 | return; 46 | } 47 | list = new ArrayList<>(onActivityLifeCycleListeners); 48 | } 49 | 50 | final int N = list.size(); 51 | for (int i = 0; i < N; i++) { 52 | list.get(i).onActivityDestroyCallback(); 53 | } 54 | } 55 | 56 | public void dispatchActivityResume() { 57 | List list; 58 | synchronized (this) { 59 | if (onActivityLifeCycleListeners == null) { 60 | return; 61 | } 62 | list = new ArrayList(onActivityLifeCycleListeners); 63 | } 64 | 65 | final int N = list.size(); 66 | for (int i = 0; i < N; i++) { 67 | list.get(i).onActivityResumeCallback(); 68 | } 69 | } 70 | 71 | public void dispatchActivityCreate(Bundle savedInstanceState) { 72 | List list; 73 | synchronized (this) { 74 | if (onActivityLifeCycleListeners == null) { 75 | return; 76 | } 77 | list = new ArrayList(onActivityLifeCycleListeners); 78 | } 79 | 80 | final int N = list.size(); 81 | for (int i = 0; i < N; i++) { 82 | list.get(i).onActivityCreateCallback(savedInstanceState); 83 | } 84 | } 85 | 86 | public void dispatchActivityPause() { 87 | List list; 88 | synchronized (this) { 89 | if (onActivityLifeCycleListeners == null) { 90 | return; 91 | } 92 | list = new ArrayList(onActivityLifeCycleListeners); 93 | } 94 | 95 | final int N = list.size(); 96 | for (int i = 0; i < N; i++) { 97 | list.get(i).onActivityPauseCallback(); 98 | } 99 | } 100 | 101 | 102 | 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/core/file/utils/FileDownloadUtil.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.core.file.utils; 2 | 3 | import android.annotation.TargetApi; 4 | import android.os.Build; 5 | import com.wangjie.androidbucket.log.Logger; 6 | import com.wangjie.androidbucket.utils.ABIOUtil; 7 | import com.wangjie.androidbucket.utils.ABTextUtil; 8 | import org.apache.http.HttpResponse; 9 | import org.apache.http.HttpStatus; 10 | import org.apache.http.NameValuePair; 11 | import org.apache.http.client.HttpClient; 12 | import org.apache.http.client.methods.HttpGet; 13 | import org.apache.http.impl.client.DefaultHttpClient; 14 | 15 | import java.io.File; 16 | import java.io.FileOutputStream; 17 | import java.io.IOException; 18 | import java.io.InputStream; 19 | 20 | /** 21 | * @author Hubert He 22 | * @version V1.0 23 | * @Description 24 | * @Createdate 14-9-15 18:33 25 | */ 26 | public class FileDownloadUtil { 27 | 28 | /** 29 | * 通过URL下载文件到指定路径 30 | * 31 | * @param url URL 32 | * @param filePath 指定路径 33 | * @param headers HTTP头 34 | * @return 35 | * @throws IOException 36 | */ 37 | @TargetApi(Build.VERSION_CODES.GINGERBREAD) 38 | public static File download(String url, String filePath, NameValuePair... headers) throws IOException { 39 | File file = new File(filePath); 40 | 41 | HttpClient client = new DefaultHttpClient(); 42 | HttpGet request = new HttpGet(url); 43 | if (!ABTextUtil.isEmpty(headers)) { 44 | for (NameValuePair header : headers) { 45 | request.addHeader(header.getName(), header.getValue()); 46 | } 47 | } 48 | InputStream is = null; 49 | FileOutputStream fos = null; 50 | try { 51 | HttpResponse response = client.execute(request); 52 | if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { 53 | is = response.getEntity().getContent(); 54 | fos = new FileOutputStream(file); 55 | byte[] buffer = new byte[1024]; 56 | int len; 57 | while ((len = is.read(buffer)) != -1) { 58 | fos.write(buffer, 0, len); 59 | } 60 | fos.flush(); 61 | } 62 | } catch (IOException e) { 63 | Logger.e("download", e); 64 | } finally { 65 | ABIOUtil.closeIO(is, fos); 66 | } 67 | return file; 68 | } 69 | 70 | /** 71 | * 通过URL下载文件到指定路径 72 | * 73 | * @param url URL 74 | * @param filePath 指定路径 75 | * @param headers HTTP头 76 | * @return 77 | * @throws IOException 78 | */ 79 | public static File downloadAnyWay(String url, String filePath, NameValuePair... headers) throws IOException { 80 | File file = new File(filePath); 81 | if (file.exists()) { 82 | file.delete(); 83 | } 84 | file.createNewFile(); 85 | return download(url, filePath, headers); 86 | } 87 | 88 | /** 89 | * 如果不存在,则下载;如果存在则不下载,直接返回 90 | * 91 | * @param url 92 | * @param filePath 93 | * @param headers 94 | * @return 95 | * @throws Exception 96 | */ 97 | public static File downloadIfNotExist(String url, String filePath, NameValuePair... headers) throws Exception { 98 | File file = new File(filePath); 99 | if (file.exists()) { 100 | return file; 101 | } 102 | return download(url, filePath, headers); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/support/cardview/CardView.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.support.cardview; 2 | 3 | 4 | import android.content.Context; 5 | import android.content.res.TypedArray; 6 | import android.os.Build; 7 | import android.util.AttributeSet; 8 | import android.widget.FrameLayout; 9 | import com.wangjie.androidbucket.R; 10 | 11 | /** 12 | * Author: wangjie 13 | * Email: tiantian.china.2@gmail.com 14 | * Date: 12/15/14. 15 | */ 16 | 17 | /** 18 | * A ViewGroup with a rounded corner background and shadow behind. 19 | *

20 | * CardView uses elevation property on L for shadows and falls back to a custom shadow implementation on 21 | * older platforms. 22 | *

23 | * Due to expensive nature of rounded corner clipping, on platforms before L, CardView does not clip its children that 24 | * intersect with rounded corners. Instead, it adds padding to avoid such intersection. 25 | * 26 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardBackgroundColor 27 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardCornerRadius 28 | */ 29 | public class CardView extends FrameLayout implements CardViewDelegate { 30 | 31 | private final static CardViewImpl IMPL; 32 | 33 | static { 34 | if (Build.VERSION.SDK_INT >= 17) { 35 | IMPL = new CardViewJellybeanMr1(); 36 | } else { 37 | IMPL = new CardViewEclairMr1(); 38 | } 39 | IMPL.initStatic(); 40 | } 41 | 42 | public CardView(Context context) { 43 | super(context); 44 | initialize(context, null, 0); 45 | } 46 | 47 | public CardView(Context context, AttributeSet attrs) { 48 | super(context, attrs); 49 | initialize(context, attrs, 0); 50 | } 51 | 52 | public CardView(Context context, AttributeSet attrs, int defStyleAttr) { 53 | super(context, attrs, defStyleAttr); 54 | initialize(context, attrs, defStyleAttr); 55 | } 56 | 57 | private void initialize(Context context, AttributeSet attrs, int defStyleAttr) { 58 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CardView, defStyleAttr, R.style.CardView_Light); 59 | int backgroundColor = a.getColor(R.styleable.CardView_cardBackgroundColor, 0); 60 | float radius = a.getDimension(R.styleable.CardView_cardCornerRadius, 0); 61 | 62 | CardShadow cardShadow = new CardShadow(); 63 | cardShadow.setShadowStartColor(a.getColor(R.styleable.CardView_shadowStartColor, context.getResources().getColor(R.color.cardview_shadow_start_color))); 64 | cardShadow.setShadowEndColor(a.getColor(R.styleable.CardView_shadowEndColor, context.getResources().getColor(R.color.cardview_shadow_end_color))); 65 | cardShadow.setShadowSize(a.getDimension(R.styleable.CardView_shadowSize, context.getResources().getDimension(R.dimen.cardview_shadow_size))); 66 | 67 | a.recycle(); 68 | IMPL.initialize(this, context, backgroundColor, radius, cardShadow); 69 | } 70 | 71 | /** 72 | * Updates the corner radius of the CardView. 73 | * 74 | * @param radius The radius in pixels of the corners of the rectangle shape 75 | * @attr ref android.support.v7.cardview.R.styleable#CardView_cardCornerRadius 76 | * @see #setRadius(float) 77 | */ 78 | public void setRadius(float radius) { 79 | IMPL.setRadius(this, radius); 80 | } 81 | 82 | /** 83 | * Returns the corner radius of the CardView. 84 | * 85 | * @return Corner radius of the CardView 86 | * @see #getRadius() 87 | */ 88 | public float getRadius() { 89 | return IMPL.getRadius(this); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/NestedListView.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.MotionEvent; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.AbsListView; 9 | import android.widget.ListAdapter; 10 | import android.widget.ListView; 11 | 12 | /** 13 | * Created with IntelliJ IDEA. 14 | * Author: wangjie email:tiantian.china.2@gmial.com 15 | * Date: 14-3-5 16 | * Time: 下午4:50 17 | */ 18 | public class NestedListView extends ListView implements View.OnTouchListener, AbsListView.OnScrollListener { 19 | 20 | private int listViewTouchAction; 21 | private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 99; 22 | 23 | public NestedListView(Context context, AttributeSet attrs) { 24 | super(context, attrs); 25 | listViewTouchAction = -1; 26 | setOnScrollListener(this); 27 | setOnTouchListener(this); 28 | } 29 | 30 | @Override 31 | public void onScroll(AbsListView view, int firstVisibleItem, 32 | int visibleItemCount, int totalItemCount) { 33 | if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) { 34 | if (listViewTouchAction == MotionEvent.ACTION_MOVE) { 35 | scrollBy(0, -1); 36 | } 37 | } 38 | } 39 | 40 | @Override 41 | public void onScrollStateChanged(AbsListView view, int scrollState) { 42 | } 43 | 44 | @Override 45 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 46 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 47 | 48 | int newHeight = 0; 49 | final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 50 | int heightSize = MeasureSpec.getSize(heightMeasureSpec); 51 | if (heightMode != MeasureSpec.EXACTLY) { 52 | ListAdapter listAdapter = getAdapter(); 53 | if (listAdapter != null && !listAdapter.isEmpty()) { 54 | int listPosition = 0; 55 | for (listPosition = 0; listPosition < listAdapter.getCount() 56 | && listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++) { 57 | View listItem = listAdapter.getView(listPosition, null, this); 58 | //now it will not throw a NPE if listItem is a ViewGroup instance 59 | if (listItem instanceof ViewGroup) { 60 | listItem.setLayoutParams(new LayoutParams( 61 | LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 62 | } 63 | listItem.measure(widthMeasureSpec, heightMeasureSpec); 64 | newHeight += listItem.getMeasuredHeight(); 65 | } 66 | newHeight += getDividerHeight() * listPosition; 67 | } 68 | if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize)) { 69 | if (newHeight > heightSize) { 70 | newHeight = heightSize; 71 | } 72 | } 73 | } else { 74 | newHeight = getMeasuredHeight(); 75 | } 76 | setMeasuredDimension(getMeasuredWidth(), newHeight); 77 | } 78 | 79 | @Override 80 | public boolean onTouch(View v, MotionEvent event) { 81 | if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) { 82 | if (listViewTouchAction == MotionEvent.ACTION_MOVE) { 83 | scrollBy(0, 1); 84 | } 85 | } 86 | return false; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/dropdownmenu/DropMenu.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.dropdownmenu; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.*; 8 | import com.wangjie.androidbucket.R; 9 | import com.wangjie.androidbucket.log.Logger; 10 | 11 | import java.util.ArrayList; 12 | import java.util.HashMap; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * Created with IntelliJ IDEA. 18 | * Author: wangjie email:tiantian.china.2@gmail.com 19 | * Date: 13-11-27 20 | * Time: 下午4:46 21 | */ 22 | public class DropMenu implements AdapterView.OnItemClickListener { 23 | private static final String TAG = DropMenu.class.getSimpleName(); 24 | private ListView popupLv; // 菜单ListView 25 | private PopupWindow popupMenu; // 菜单控件 26 | private int backgroundRes; 27 | private int itemSelectorBg; 28 | private Context context; 29 | 30 | private IDropMenu iDropMenu; 31 | 32 | public static final String KEY_TITLE = "title"; 33 | 34 | public static PopupWindow createDropDownMenu(Context context, IDropMenu iDropMenu, int backgroundRes, int itemSelectorBg){ 35 | DropMenu dropMenu = new DropMenu(context, iDropMenu, backgroundRes, itemSelectorBg); 36 | return dropMenu.getPopupMenu(); 37 | } 38 | 39 | public DropMenu(Context context, IDropMenu iDropMenu, int backgroundRes, int itemSelectorBg) { 40 | this.context = context; 41 | this.iDropMenu = iDropMenu; 42 | this.backgroundRes = backgroundRes; 43 | this.itemSelectorBg = itemSelectorBg; 44 | initPopupMenu(); 45 | } 46 | 47 | 48 | /** 49 | * 初始化下拉菜单 50 | */ 51 | private void initPopupMenu() { 52 | LayoutInflater inflater = LayoutInflater.from(context); 53 | View view = inflater.inflate(R.layout.ab_drop_menu, null); 54 | List> items = getMenuData(); 55 | if(null == items){ 56 | return; 57 | } 58 | 59 | DropMenuAdapter adapter = new DropMenuAdapter(context, items, itemSelectorBg); 60 | 61 | popupLv = (ListView) view.findViewById(R.id.ab_drop_menu_lv); 62 | popupLv.setAdapter(adapter); 63 | popupLv.setOnItemClickListener(this); 64 | 65 | popupMenu = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, 66 | ViewGroup.LayoutParams.WRAP_CONTENT); 67 | popupMenu.setBackgroundDrawable(context.getResources().getDrawable(backgroundRes)); 68 | popupMenu.setAnimationStyle(android.R.style.Animation_Dialog); 69 | popupMenu.setFocusable(true); 70 | 71 | } 72 | 73 | @Override 74 | public void onItemClick(AdapterView parent, View view, int position, long id) { 75 | iDropMenu.onDropDownMenuItemClick(parent, view, position, id); 76 | } 77 | 78 | private List> getMenuData() { 79 | String[] itemTitles = iDropMenu.getDropDownMenuItems(); 80 | if(null == itemTitles || itemTitles.length <= 0){ 81 | Logger.d(TAG, "drop down menu items have no items!"); 82 | return null; 83 | } 84 | List> list = new ArrayList>(); 85 | Map map; 86 | 87 | for(int i = 0; i < itemTitles.length; i++){ 88 | map = new HashMap(); 89 | map.put(KEY_TITLE, itemTitles[i]); 90 | list.add(map); 91 | } 92 | 93 | return list; 94 | } 95 | 96 | public ListView getPopupLv() { 97 | return popupLv; 98 | } 99 | 100 | public void setPopupLv(ListView popupLv) { 101 | this.popupLv = popupLv; 102 | } 103 | 104 | public PopupWindow getPopupMenu() { 105 | return popupMenu; 106 | } 107 | 108 | public void setPopupMenu(PopupWindow popupMenu) { 109 | this.popupMenu = popupMenu; 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/customviews/dropdownmenu/common/CommonDropMenu.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.customviews.dropdownmenu.common; 2 | 3 | import android.content.Context; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.AdapterView; 8 | import android.widget.BaseAdapter; 9 | import android.widget.ListView; 10 | import android.widget.PopupWindow; 11 | import com.wangjie.androidbucket.R; 12 | import com.wangjie.androidbucket.customviews.dropdownmenu.DropMenuAdapter; 13 | import com.wangjie.androidbucket.customviews.dropdownmenu.IDropMenu; 14 | import com.wangjie.androidbucket.log.Logger; 15 | import com.wangjie.androidbucket.utils.ABTextUtil; 16 | 17 | import java.util.ArrayList; 18 | import java.util.HashMap; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | /** 23 | * Created with IntelliJ IDEA. 24 | * Author: wangjie email:tiantian.china.2@gmail.com 25 | * Date: 13-11-27 26 | * Time: 下午4:46 27 | */ 28 | public class CommonDropMenu implements AdapterView.OnItemClickListener { 29 | private static final String TAG = CommonDropMenu.class.getSimpleName(); 30 | 31 | public static interface ICommonDropMenu{ 32 | /** 33 | * 下拉菜单item点击回调方法 34 | * @param parent 35 | * @param view 36 | * @param position 37 | * @param id 38 | */ 39 | public void onDropDownMenuItemClick(AdapterView parent, View view, int position, long id); 40 | } 41 | 42 | private ListView popupLv; // 菜单ListView 43 | private PopupWindow popupMenu; // 菜单控件 44 | private int backgroundRes; 45 | private Context context; 46 | 47 | private ICommonDropMenu iDropMenu; 48 | 49 | public static CommonDropMenu createCommonDropDownMenu(Context context, ICommonDropMenu iDropMenu, int backgroundRes){ 50 | return new CommonDropMenu<>(context, iDropMenu, backgroundRes); 51 | } 52 | 53 | public CommonDropMenu(Context context, ICommonDropMenu iDropMenu, int backgroundRes) { 54 | this.context = context; 55 | this.iDropMenu = iDropMenu; 56 | this.backgroundRes = backgroundRes; 57 | initPopupMenu(); 58 | } 59 | 60 | 61 | /** 62 | * 初始化下拉菜单 63 | */ 64 | private void initPopupMenu() { 65 | LayoutInflater inflater = LayoutInflater.from(context); 66 | View view = inflater.inflate(R.layout.ab_drop_menu, null); 67 | if(null == iDropMenu){ 68 | Logger.e(TAG, "iDropMenu is null!"); 69 | return; 70 | } 71 | 72 | popupLv = (ListView) view.findViewById(R.id.ab_drop_menu_lv); 73 | // popupLv.setAdapter(adapter); 74 | popupLv.setOnItemClickListener(this); 75 | 76 | popupMenu = new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT, 77 | ViewGroup.LayoutParams.WRAP_CONTENT); 78 | popupMenu.setBackgroundDrawable(context.getResources().getDrawable(backgroundRes)); 79 | popupMenu.setAnimationStyle(android.R.style.Animation_Dialog); 80 | popupMenu.setFocusable(true); 81 | 82 | } 83 | 84 | private BaseAdapter adapter; 85 | public void setAdapter(BaseAdapter adapter){ 86 | this.adapter = adapter; 87 | popupLv.setAdapter(this.adapter); 88 | } 89 | 90 | public BaseAdapter getAdapter() { 91 | return adapter; 92 | } 93 | 94 | @Override 95 | public void onItemClick(AdapterView parent, View view, int position, long id) { 96 | iDropMenu.onDropDownMenuItemClick(parent, view, position, id); 97 | } 98 | 99 | 100 | public ListView getPopupLv() { 101 | return popupLv; 102 | } 103 | 104 | public void setPopupLv(ListView popupLv) { 105 | this.popupLv = popupLv; 106 | } 107 | 108 | public PopupWindow getPopupMenu() { 109 | return popupMenu; 110 | } 111 | 112 | public void setPopupMenu(PopupWindow popupMenu) { 113 | this.popupMenu = popupMenu; 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/utils/ABPrefsUtil.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.utils; 2 | 3 | import android.annotation.TargetApi; 4 | import android.content.Context; 5 | import android.content.SharedPreferences; 6 | import android.os.Build; 7 | 8 | import java.util.Map; 9 | import java.util.Set; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: wangjie 14 | * Date: 14-3-29 15 | * Time: 上午12:18 16 | * To change this template use File | Settings | File Templates. 17 | */ 18 | public class ABPrefsUtil { 19 | private static ABPrefsUtil prefsUtil; 20 | public Context context; 21 | public SharedPreferences prefs; 22 | public SharedPreferences.Editor editor; 23 | 24 | public synchronized static ABPrefsUtil getInstance(){ 25 | return prefsUtil; 26 | } 27 | 28 | public static void init(Context context, String prefsname, int mode) { 29 | prefsUtil = new ABPrefsUtil(); 30 | prefsUtil.context = context; 31 | prefsUtil.prefs = prefsUtil.context.getSharedPreferences(prefsname, mode); 32 | prefsUtil.editor = prefsUtil.prefs.edit(); 33 | } 34 | 35 | private ABPrefsUtil() { 36 | } 37 | 38 | 39 | public boolean getBoolean(String key, boolean defaultVal){ 40 | return this.prefs.getBoolean(key, defaultVal); 41 | } 42 | public boolean getBoolean(String key){ 43 | return this.prefs.getBoolean(key, false); 44 | } 45 | 46 | 47 | public String getString(String key, String defaultVal){ 48 | return this.prefs.getString(key, defaultVal); 49 | } 50 | public String getString(String key){ 51 | return this.prefs.getString(key, null); 52 | } 53 | 54 | public int getInt(String key, int defaultVal){ 55 | return this.prefs.getInt(key, defaultVal); 56 | } 57 | public int getInt(String key){ 58 | return this.prefs.getInt(key, 0); 59 | } 60 | 61 | 62 | public float getFloat(String key, float defaultVal){ 63 | return this.prefs.getFloat(key, defaultVal); 64 | } 65 | public float getFloat(String key){ 66 | return this.prefs.getFloat(key, 0f); 67 | } 68 | 69 | public long getLong(String key, long defaultVal){ 70 | return this.prefs.getLong(key, defaultVal); 71 | } 72 | public long getLong(String key){ 73 | return this.prefs.getLong(key, 0l); 74 | } 75 | 76 | @TargetApi(Build.VERSION_CODES.HONEYCOMB) 77 | public Set getStringSet(String key, Set defaultVal){ 78 | return this.prefs.getStringSet(key, defaultVal); 79 | } 80 | @TargetApi(Build.VERSION_CODES.HONEYCOMB) 81 | public Set getStringSet(String key){ 82 | return this.prefs.getStringSet(key, null); 83 | } 84 | 85 | public Map getAll(){ 86 | return this.prefs.getAll(); 87 | } 88 | 89 | 90 | public ABPrefsUtil putString(String key, String value){ 91 | editor.putString(key, value); 92 | // editor.commit(); 93 | return this; 94 | } 95 | 96 | public ABPrefsUtil putInt(String key, int value){ 97 | editor.putInt(key, value); 98 | // editor.commit(); 99 | return this; 100 | } 101 | 102 | public ABPrefsUtil putFloat(String key, float value){ 103 | editor.putFloat(key, value); 104 | // editor.commit(); 105 | return this; 106 | } 107 | 108 | public ABPrefsUtil putLong(String key, long value){ 109 | editor.putLong(key, value); 110 | // editor.commit(); 111 | return this; 112 | } 113 | 114 | public ABPrefsUtil putBoolean(String key, boolean value){ 115 | editor.putBoolean(key, value); 116 | // editor.commit(); 117 | return this; 118 | } 119 | public void commit(){ 120 | editor.commit(); 121 | } 122 | 123 | @TargetApi(Build.VERSION_CODES.HONEYCOMB) 124 | public ABPrefsUtil putStringSet(String key, Set value){ 125 | editor.putStringSet(key, value); 126 | editor.commit(); 127 | return this; 128 | } 129 | 130 | 131 | } 132 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/services/network/toolbox/StringHippoHttpRequest.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.services.network.toolbox; 2 | 3 | import com.wangjie.androidbucket.services.CancelableTask; 4 | import com.wangjie.androidbucket.services.network.HippoHttpRequest; 5 | import com.wangjie.androidbucket.services.network.NetworkResponse; 6 | import com.wangjie.androidbucket.services.network.HippoResponse; 7 | import com.wangjie.androidbucket.services.network.RequestListener; 8 | import com.wangjie.androidbucket.services.network.exception.HippoException; 9 | import org.apache.http.NameValuePair; 10 | 11 | import java.io.UnsupportedEncodingException; 12 | import java.util.Collection; 13 | 14 | /** 15 | * @author Hubert He 16 | * @version V1.0 17 | * @Description 18 | * @Createdate 14-9-24 17:09 19 | */ 20 | public class StringHippoHttpRequest extends HippoHttpRequest { 21 | 22 | private final String encoding; 23 | 24 | private Collection cancelableTaskCollection; 25 | 26 | /** 27 | * 完全构造函数 28 | * 29 | * @param method 30 | * @param url 31 | * @param headers 32 | * @param body 33 | * @param listener 34 | * @param errorListener 35 | */ 36 | public StringHippoHttpRequest(int method, 37 | String encoding, 38 | String url, 39 | NameValuePair[] headers, 40 | byte[] body, 41 | RequestListener listener, 42 | HippoResponse.ErrorListener errorListener) { 43 | super(method, url, headers, body, listener, errorListener); 44 | this.encoding = encoding; 45 | } 46 | 47 | 48 | /** 49 | * 构造函数 50 | * 51 | * @param url 52 | * @param headers 53 | * @param body 54 | * @param listener 55 | * @param errorListener 56 | */ 57 | public StringHippoHttpRequest(String url, 58 | NameValuePair[] headers, 59 | byte[] body, 60 | RequestListener listener, 61 | HippoResponse.ErrorListener errorListener) { 62 | this(Method.GET, DEFAULT_RESPONSE_ENCODING, url, headers, body, listener, errorListener); 63 | } 64 | 65 | /** 66 | * 构造函数 67 | * 68 | * @param url 69 | * @param headers 70 | * @param body 71 | * @param listener 72 | * @param errorListener 73 | */ 74 | public StringHippoHttpRequest(int method, 75 | String url, 76 | NameValuePair[] headers, 77 | byte[] body, 78 | RequestListener listener, 79 | HippoResponse.ErrorListener errorListener) { 80 | this(method, DEFAULT_RESPONSE_ENCODING, url, headers, body, listener, errorListener); 81 | } 82 | 83 | @Override 84 | public HippoResponse parseResponse(NetworkResponse response) { 85 | HippoResponse hippoResponse; 86 | if (response.isSuccess()) { 87 | try { 88 | hippoResponse = new HippoResponse<>(new String(response.getData(), encoding)); 89 | } catch (UnsupportedEncodingException e) { 90 | hippoResponse = new HippoResponse<>(new HippoException("Oops! Unsupported encoding, you must kidding me!", e)); 91 | } 92 | } else { 93 | hippoResponse = new HippoResponse<>(new HippoException("Cannot parse response due to this error happen.", response.getError())); 94 | } 95 | return hippoResponse; 96 | } 97 | 98 | @Override 99 | public void addListener(Collection cancelableTaskCollection) { 100 | this.cancelableTaskCollection = cancelableTaskCollection; 101 | } 102 | 103 | @Override 104 | public void remove() { 105 | if (cancelableTaskCollection != null) { 106 | cancelableTaskCollection.remove(this); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/utils/ABJsonUtil.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.utils; 2 | 3 | import org.json.JSONArray; 4 | import org.json.JSONException; 5 | import org.json.JSONObject; 6 | 7 | /** 8 | * 对json解析的包装 9 | * @author wangjie 10 | * @version 创建时间:2013-3-26 上午11:08:45 11 | */ 12 | public class ABJsonUtil { 13 | 14 | public static String getString(JSONObject jo, String key){ 15 | try { 16 | return jo.has(key) ? jo.getString(key) : ""; 17 | } catch (Exception e) { 18 | return ""; 19 | } 20 | } 21 | 22 | public static String getString(JSONObject jo, String key, String defaultValue){ 23 | try { 24 | return jo.has(key) ? jo.getString(key) : defaultValue; 25 | } catch (Exception e) { 26 | return defaultValue; 27 | } 28 | } 29 | 30 | 31 | 32 | public static int getInt(JSONObject jo, String key){ 33 | try { 34 | return jo.has(key) ? jo.getInt(key) : 0; 35 | } catch (Exception e) { 36 | return 0; 37 | } 38 | } 39 | 40 | public static int getInt(JSONObject jo, String key, int defaultValue){ 41 | try { 42 | return jo.has(key) ? jo.getInt(key) : defaultValue; 43 | } catch (Exception e) { 44 | return defaultValue; 45 | } 46 | } 47 | 48 | 49 | 50 | public static long getLong(JSONObject jo, String key){ 51 | try { 52 | return jo.has(key) ? jo.getLong(key) : 0l; 53 | } catch (Exception e) { 54 | return 0l; 55 | } 56 | } 57 | public static long getLong(JSONObject jo, String key, long defaultValue){ 58 | try { 59 | return jo.has(key) ? jo.getLong(key) : defaultValue; 60 | } catch (Exception e) { 61 | return defaultValue; 62 | } 63 | } 64 | 65 | 66 | public static boolean getBoolean(JSONObject jo, String key){ 67 | try { 68 | return jo.has(key) && jo.getBoolean(key); 69 | } catch (Exception e) { 70 | return false; 71 | } 72 | } 73 | 74 | public static boolean getBoolean(JSONObject jo, String key, boolean defaultValue){ 75 | try { 76 | return jo.has(key) ? jo.getBoolean(key) : defaultValue; 77 | } catch (Exception e) { 78 | return defaultValue; 79 | } 80 | } 81 | 82 | 83 | 84 | public static double getDouble(JSONObject jo, String key){ 85 | try { 86 | return jo.has(key) ? jo.getDouble(key) : 0d; 87 | } catch (Exception e) { 88 | return 0d; 89 | } 90 | } 91 | 92 | public static double getDouble(JSONObject jo, String key, double defaultValue){ 93 | try { 94 | return jo.has(key) ? jo.getDouble(key) : defaultValue; 95 | } catch (Exception e) { 96 | return defaultValue; 97 | } 98 | } 99 | 100 | 101 | 102 | public static JSONObject getJSONObject(JSONObject jo, String key){ 103 | try { 104 | return jo.has(key) ? jo.getJSONObject(key) : null; 105 | } catch (Exception e) { 106 | return null; 107 | } 108 | } 109 | public static JSONObject getJSONArray(JSONObject jo, String key, JSONObject defaultValue){ 110 | try { 111 | return jo.has(key) ? jo.getJSONObject(key) : defaultValue; 112 | } catch (Exception e) { 113 | return defaultValue; 114 | } 115 | } 116 | 117 | 118 | public static JSONArray getJSONArray(JSONObject jo, String key){ 119 | try { 120 | return jo.has(key) ? jo.getJSONArray(key) : null; 121 | } catch (Exception e) { 122 | return null; 123 | } 124 | } 125 | public static JSONArray getJSONArray(JSONObject jo, String key, JSONArray defaultValue){ 126 | try { 127 | return jo.has(key) ? jo.getJSONArray(key) : defaultValue; 128 | } catch (Exception e) { 129 | return defaultValue; 130 | } 131 | } 132 | 133 | 134 | 135 | // util 136 | public static boolean isEmpty(JSONArray ja){ 137 | return null == ja || ja.length() <= 0; 138 | } 139 | 140 | 141 | } 142 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/security/des3/Base64.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.security.des3; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | 7 | /** 8 | * Base64编码工具类 9 | * Created with IntelliJ IDEA. 10 | * Author: wangjie email:tiantian.china.2@gmail.com 11 | * Date: 14-4-4 12 | * Time: 上午10:46 13 | */ 14 | public class Base64 { 15 | private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); 16 | 17 | public static String encode(byte[] data) { 18 | int start = 0; 19 | int len = data.length; 20 | StringBuffer buf = new StringBuffer(data.length * 3 / 2); 21 | 22 | int end = len - 3; 23 | int i = start; 24 | int n = 0; 25 | 26 | while (i <= end) { 27 | int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 0x0ff) << 8) | (((int) data[i + 2]) & 0x0ff); 28 | 29 | buf.append(legalChars[(d >> 18) & 63]); 30 | buf.append(legalChars[(d >> 12) & 63]); 31 | buf.append(legalChars[(d >> 6) & 63]); 32 | buf.append(legalChars[d & 63]); 33 | 34 | i += 3; 35 | 36 | if (n++ >= 14) { 37 | n = 0; 38 | buf.append(" "); 39 | } 40 | } 41 | 42 | if (i == start + len - 2) { 43 | int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 255) << 8); 44 | 45 | buf.append(legalChars[(d >> 18) & 63]); 46 | buf.append(legalChars[(d >> 12) & 63]); 47 | buf.append(legalChars[(d >> 6) & 63]); 48 | buf.append("="); 49 | } else if (i == start + len - 1) { 50 | int d = (((int) data[i]) & 0x0ff) << 16; 51 | 52 | buf.append(legalChars[(d >> 18) & 63]); 53 | buf.append(legalChars[(d >> 12) & 63]); 54 | buf.append("=="); 55 | } 56 | 57 | return buf.toString(); 58 | } 59 | 60 | private static int decode(char c) { 61 | if (c >= 'A' && c <= 'Z') 62 | return ((int) c) - 65; 63 | else if (c >= 'a' && c <= 'z') 64 | return ((int) c) - 97 + 26; 65 | else if (c >= '0' && c <= '9') 66 | return ((int) c) - 48 + 26 + 26; 67 | else 68 | switch (c) { 69 | case '+': 70 | return 62; 71 | case '/': 72 | return 63; 73 | case '=': 74 | return 0; 75 | default: 76 | throw new RuntimeException("unexpected code: " + c); 77 | } 78 | } 79 | 80 | /** 81 | * Decodes the given Base64 encoded String to a new byte array. The byte array holding the decoded data is returned. 82 | */ 83 | 84 | public static byte[] decode(String s) { 85 | 86 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); 87 | try { 88 | decode(s, bos); 89 | } catch (IOException e) { 90 | throw new RuntimeException(); 91 | } 92 | byte[] decodedBytes = bos.toByteArray(); 93 | try { 94 | bos.close(); 95 | bos = null; 96 | } catch (IOException ex) { 97 | System.err.println("Error while decoding BASE64: " + ex.toString()); 98 | } 99 | return decodedBytes; 100 | } 101 | 102 | private static void decode(String s, OutputStream os) throws IOException { 103 | int i = 0; 104 | 105 | int len = s.length(); 106 | 107 | while (true) { 108 | while (i < len && s.charAt(i) <= ' ') 109 | i++; 110 | 111 | if (i == len) 112 | break; 113 | 114 | int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12) + (decode(s.charAt(i + 2)) << 6) + (decode(s.charAt(i + 3))); 115 | 116 | os.write((tri >> 16) & 255); 117 | if (s.charAt(i + 2) == '=') 118 | break; 119 | os.write((tri >> 8) & 255); 120 | if (s.charAt(i + 3) == '=') 121 | break; 122 | os.write(tri & 255); 123 | 124 | i += 4; 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/com/wangjie/androidbucket/application/HttpApplicationController.java: -------------------------------------------------------------------------------- 1 | package com.wangjie.androidbucket.application; 2 | 3 | import android.util.Log; 4 | 5 | import com.wangjie.androidbucket.services.BaseAccessResponse; 6 | import com.wangjie.androidbucket.services.network.HippoRequest; 7 | import com.wangjie.androidbucket.services.network.HippoRequestQueue; 8 | import com.wangjie.androidbucket.services.network.http.SSLSocketFactoryEx; 9 | import com.wangjie.androidbucket.services.network.toolbox.HttpNetwork; 10 | 11 | import org.apache.http.HttpVersion; 12 | import org.apache.http.client.HttpClient; 13 | import org.apache.http.conn.ClientConnectionManager; 14 | import org.apache.http.conn.scheme.Scheme; 15 | import org.apache.http.conn.scheme.SchemeRegistry; 16 | import org.apache.http.conn.ssl.SSLSocketFactory; 17 | import org.apache.http.impl.client.DefaultHttpClient; 18 | import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; 19 | import org.apache.http.params.BasicHttpParams; 20 | import org.apache.http.params.HttpConnectionParams; 21 | import org.apache.http.params.HttpParams; 22 | import org.apache.http.params.HttpProtocolParams; 23 | import org.apache.http.protocol.HTTP; 24 | 25 | import java.security.KeyStore; 26 | import java.util.concurrent.TimeUnit; 27 | 28 | /** 29 | * @author Hubert He 30 | * @version V1.0 31 | * @Description 32 | * @Createdate 14-9-21 11:04 33 | */ 34 | public class HttpApplicationController extends ABApplication { 35 | 36 | private static final String TAG = HttpApplicationController.class.getSimpleName(); 37 | 38 | /** 39 | * 请求队列 40 | */ 41 | protected HippoRequestQueue httpRequestQueue; 42 | 43 | /** 44 | * 实例 45 | */ 46 | private static HttpApplicationController instance; 47 | 48 | @Override 49 | public void onCreate() { 50 | super.onCreate(); 51 | instance = this; 52 | Log.d(TAG, "On application create"); 53 | } 54 | 55 | public static synchronized HttpApplicationController getInstance() { 56 | return instance; 57 | } 58 | 59 | protected HippoRequestQueue getHttpRequestQueue() { 60 | if (httpRequestQueue == null) { 61 | HttpNetwork networkExecutor = new HttpNetwork(); 62 | httpRequestQueue = HippoRequestQueue.newHippoRequestQueue(networkExecutor); 63 | } 64 | return httpRequestQueue; 65 | } 66 | 67 | 68 | /** 69 | * Adds the specified request to the global queue, if tag is specified 70 | * then it is used else Default TAG is used. 71 | * 72 | * @param req 73 | */ 74 | public void addToRequestQueue(HippoRequest req) { 75 | // set the default tag if tag is empty 76 | getHttpRequestQueue().add(req); 77 | } 78 | 79 | /** 80 | * 获取SSL连接 81 | * 82 | * @return 83 | */ 84 | public DefaultHttpClient getHttpClient() { 85 | int httpPort = 80; 86 | int httpsPort = 443; 87 | int soTimeout = 20000; 88 | int connectionTimeout = 20000; 89 | try { 90 | KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); 91 | trustStore.load(null, null); 92 | 93 | SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore); 94 | sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 95 | 96 | HttpParams params = new BasicHttpParams(); 97 | 98 | // 设置超时时间 99 | HttpConnectionParams.setConnectionTimeout(params, connectionTimeout); 100 | HttpConnectionParams.setSoTimeout(params, soTimeout); 101 | HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 102 | HttpProtocolParams.setContentCharset(params, HTTP.UTF_8); 103 | 104 | SchemeRegistry registry = new SchemeRegistry(); 105 | registry.register(new Scheme("http", sf, httpPort)); 106 | registry.register(new Scheme("https", sf, httpsPort)); 107 | 108 | ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry); 109 | ccm.closeIdleConnections(120, TimeUnit.SECONDS); 110 | return new DefaultHttpClient(ccm, params); 111 | } catch (Exception e) { 112 | return new DefaultHttpClient(); 113 | } 114 | } 115 | } 116 | --------------------------------------------------------------------------------