@iar
2016-09-24T01:49:46.000000Z
字数 13036
阅读 157
BurningFire
C:\Users\Administrator\StudioProjects\BF-Android-App\app\src\main\java\com\burningfire\BFandroidapp>tree /FFolder PATH listingVolume serial number is C038-3181C:.├───api│ AuthorizationInterceptor.java│ DiscoverResponse.java│ CitieReviewsResponse.java│ CitieVideosResponse.java│ TheCitieDbClient.java│ TheCitieDbService.java│├───data│ FavoritesService.java│ Citie.java│ CitieReview.java│ CitiesContract.java│ CitiesDbHelper.java│ CitiesProvider.java│ CitiesService.java│ CitieVideo.java│ Sort.java│ SortHelper.java│├───ui│ │ EndlessRecyclerViewOnScrollListener.java│ │ ItemOffsetDecoration.java│ │ MainActivity.java│ │ ProportionalImageView.java│ │ SortingDialogFragment.java│ │ SplashActivity.java│ ││ ├───detail│ │ CitieDetailActivity.java│ │ CitieDetailFragment.java│ │ CitieReviewsAdapter.java│ │ CitieReviewViewHolder.java│ │ CitieVideosAdapter.java│ │ CitieVideoViewHolder.java│ ││ └───grid│ AbstractCitiesGridFragment.java│ FavoritesGridFragment.java│ CitieGridItemViewHolder.java│ CitiesAdapter.java│ CitiesGridFragment.java│└───utilCursorRecyclerViewAdapter.javaOnItemClickListener.javaOnItemSelectedListener.java
chyrta/AndroidOnboarder to implement a card based introduction of the services that Burning Fire hosted,
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);AhoyOnboarderCard ahoyOnboarderCard1 = new AhoyOnboarderCard("旅行安排", "旅行是给自己一个重新认识自己,认识世界的机会.", R.drawable.backpack);AhoyOnboarderCard ahoyOnboarderCard2 = new AhoyOnboarderCard("美食推荐", "不被时间和社会所束缚,幸福的填饱肚子的时候,短时间内变得随心所欲,变得“自由”不被谁打扰。毫不费神的吃东西这种孤高的行为,这种行为正是平等地赋予现代人的---最高的治愈!.", R.drawable.food);AhoyOnboarderCard ahoyOnboarderCard3 = new AhoyOnboarderCard("婚礼蜜月", "一生一次 永生难忘, 提供婚纱照, 蜜月随拍, 婚礼婚庆, 宝宝百天照.", R.drawable.chalk);AhoyOnboarderCard ahoyOnboarderCard4 = new AhoyOnboarderCard("投资移民", "私人订制的移民计划,帮助您在异国他乡安定生活, 为孩子提供最好的生活环境和教育, 走向人生巅峰.", R.drawable.house);AhoyOnboarderCard ahoyOnboarderCard5 = new AhoyOnboarderCard("电子商务及奥特莱斯供货", "MIAMI BELLE是公司为女性员工提供的一个福利性营业平台. 在广大女性员工的努力下,建立MIAMI BELLE品牌并在线销售该品牌产品.", R.drawable.wallet);AhoyOnboarderCard ahoyOnboarderCard6 = new AhoyOnboarderCard("美国游学", "世界著名大学游学夏令营, 为您的孩子提前跨进名校.", R.drawable.school);ahoyOnboarderCard1.setBackgroundColor(R.color.black_transparent);ahoyOnboarderCard2.setBackgroundColor(R.color.black_transparent);ahoyOnboarderCard3.setBackgroundColor(R.color.black_transparent);ahoyOnboarderCard4.setBackgroundColor(R.color.black_transparent);ahoyOnboarderCard5.setBackgroundColor(R.color.black_transparent);ahoyOnboarderCard6.setBackgroundColor(R.color.black_transparent);List<AhoyOnboarderCard> pages = new ArrayList<>();pages.add(ahoyOnboarderCard1);pages.add(ahoyOnboarderCard2);pages.add(ahoyOnboarderCard3);pages.add(ahoyOnboarderCard4);pages.add(ahoyOnboarderCard5);pages.add(ahoyOnboarderCard6);for (AhoyOnboarderCard page : pages) {page.setTitleColor(R.color.white);page.setDescriptionColor(R.color.grey_200);}setFinishButtonTitle("Get Started");showNavigationControls(true);//setGradientBackground();setImageBackground(R.drawable.download);Typeface face = Typeface.createFromAsset(getAssets(), "fonts/Roboto-Light.ttf");//setFont(face);setInactiveIndicatorColor(R.color.grey_600);setActiveIndicatorColor(R.color.white);setOnboardPages(pages);}





public abstract class AndroidOnBoarddActiviy extends AppCompatActivity implements View.OnClickListener, ViewPager.OnPageChangeListener, then the main logic in the onCreate is by integrate various UI interface method calls, so as to implement functionality through hook functions(somewhat callback mechnism). The implementation is shown below:
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_ahoy);setStatusBackgroundColor();hideActionBar();parentLayout = (RelativeLayout) findViewById(R.id.parent_layout);circleIndicatorView = (CircleIndicatorView) findViewById(R.id.circle_indicator_view);btnSkip = (TextView) findViewById(R.id.btn_skip);buttonsLayout = (FrameLayout) findViewById(R.id.buttons_layout);navigationControls = (FrameLayout) findViewById(R.id.navigation_layout);ivNext = (ImageView) findViewById(R.id.ivNext);ivPrev = (ImageView) findViewById(R.id.ivPrev);backgroundImage = (ImageView) findViewById(R.id.background_image);backgroundImageOverlay = (View) findViewById(R.id.background_image_overlay);vpOnboarderPager = (ViewPager) findViewById(R.id.vp_pager);vpOnboarderPager.addOnPageChangeListener(this);btnSkip.setOnClickListener(this);ivPrev.setOnClickListener(this);ivNext.setOnClickListener(this);hideFinish(false);fadeOut(ivPrev, false);}
@Overridepublic void onClick(View v) {int i = v.getId();boolean isInFirstPage = vpOnboarderPager.getCurrentItem() == 0;boolean isInLastPage = vpOnboarderPager.getCurrentItem() == ahoyOnboarderAdapter.getCount() - 1;if (i == R.id.btn_skip && isInLastPage) {onFinishButtonPressed();} else if (i == R.id.ivPrev && !isInFirstPage) {vpOnboarderPager.setCurrentItem(vpOnboarderPager.getCurrentItem() - 1);} else if (i == R.id.ivNext && !isInLastPage) {vpOnboarderPager.setCurrentItem(vpOnboarderPager.getCurrentItem() + 1);}}
private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {if (mGoogleApiClient.isConnected()) {Log.i(TAG, "Starting autocomplete query for: " + constraint);PendingResult<AutocompletePredictionBuffer> results =Places.GeoDataApi.getAutocompletePredictions(mGoogleApiClient,constraint.toString(), mBounds, mPlaceFilter);AutocompletePredictionBuffer autocompletePredictions = results.await(60, TimeUnit.SECONDS);final Status status = autocompletePredictions.getStatus();if (!status.isSuccess()) {Toast.makeText(getContext(), "Error contacting API: " + status.toString(),Toast.LENGTH_SHORT).show();Log.e(TAG, "Error getting autocomplete prediction API call: " + status.toString());autocompletePredictions.release();return null;}Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()+ " predictions.");return DataBufferUtils.freezeAndClose(autocompletePredictions);}Log.e(TAG, "Google API client is not connected for autocomplete query.");return null;}

Example: C:\Users\Administrator\.android\debug.keystore instead of ~/.android/debug.keystore 
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context.getApplicationContext());if(status == ConnectionResult.SUCCESS) {//OK}else if(status == ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED){Toast.makeText(context,"please udpate your google play service",Toast.LENGTH_SHORT).show();}mGoogleApiClient = new GoogleApiClient.Builder(context)//.enableAutoManage(activity, 0 /* clientId */, this).addApi(Places.GEO_DATA_API).addConnectionCallbacks(this).addOnConnectionFailedListener(this)// .addApi(LocationServices.API).build();}@Overridepublic void onConnectionFailed(ConnectionResult connectionResult) {Log.e(TAG, "onConnectionFailed: ConnectionResult.getErrorCode() = "+ connectionResult.getErrorCode());// TODO(Developer): Check error code and notify the user of error state and resolution.Toast.makeText(context,"Failed to connect to Google geo API Client: Error " + connectionResult.getErrorCode(),Toast.LENGTH_SHORT).show();}
The Architecture I followed is: Uncle Bob's Clean Architecture.
Here is the screen shots:
, 
public class MainActivity extends AppCompatActivity implements OnItemSelectedListener,NavigationView.OnNavigationItemSelectedListener {...@BindView(R.id.drawer_layout)DrawerLayout drawerLayout;@BindView(R.id.navigation_view)NavigationView navigationView;@BindView(R.id.coordinator_layout)CoordinatorLayout coordinatorLayout;@BindView(R.id.toolbar)Toolbar toolbar;@Nullable@BindView(R.id.movie_detail_container)ScrollView movieDetailContainer;@Nullable@BindView(R.id.fab)FloatingActionButton fab;...protected void onCreate() {...ButterKnife.bind(this);...}...}
.\
public static TheCitiesDbService getInstance(Context context) {synchronized (TheCitiesDbService.class) {if (instance == null) {Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).client(getClient(context)).build();instance = retrofit.create(TheCitiesDbService.class);}}return instance;}
public interface TheCitiesDbService {@GET("city/{id}/videos")Observable<CitiesVideosResponse> getCityVideos(@Path("id") long cityId);@GET("city/{id}/reviews")Observable<CityReviewsResponse> getCityReviews(@Path("id") long cityId);@GET("discover/city")Observable<DiscoverResponse<City>> discovercities(@Query("sort_by") String sortBy, @Query("page") Integer page);}

For instance, In data's service class: CitiesService, I implement callDiscoverCities() function with observers to functionally react to the scheduling: specify the Scheduler on which an observer will observe this Observable
private void callDiscoverCities(String sort, @Nullable Integer page) {TheCitieDbService service = TheCitieDbClient.getInstance(context);service.discoverCities(sort, page).subscribeOn(Schedulers.newThread()).doOnNext(discoverCitiesResponse -> clearCitiesSortTableIfNeeded(discoverCitiesResponse)).doOnNext(discoverCitiesResponse -> logResponse(discoverCitiesResponse)).map(discoverCitiesResponse -> discoverCitiesResponse.getResults()).flatMap(Cities -> Observable.from(Cities)).map(Citie -> saveCitie(Citie)).map(CitieUri -> CitiesContract.CitieEntry.getIdFromUri(CitieUri)).doOnNext(CitieId -> saveCitieReference(CitieId)).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<Long>() {@Overridepublic void onCompleted() {loading = false;sendUpdateFinishedBroadcast(true);}@Overridepublic void onError(Throwable e) {loading = false;sendUpdateFinishedBroadcast(false);}@Overridepublic void onNext(Long aLong) {// do nothing}});}