@iar
2016-09-24T09:49:46.000000Z
字数 13036
阅读 131
BurningFire
C:\Users\Administrator\StudioProjects\BF-Android-App\app\src\main\java\com\burningfire\BFandroidapp>tree /F
Folder PATH listing
Volume serial number is C038-3181
C:.
├───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
│
└───util
CursorRecyclerViewAdapter.java
OnItemClickListener.java
OnItemSelectedListener.java
chyrta/AndroidOnboarder
to implement a card based introduction of the services that Burning Fire hosted,
@Override
protected 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:
@Override
protected 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);
}
@Override
public 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
@Override
protected 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();
}
@Override
public 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>() {
@Override
public void onCompleted() {
loading = false;
sendUpdateFinishedBroadcast(true);
}
@Override
public void onError(Throwable e) {
loading = false;
sendUpdateFinishedBroadcast(false);
}
@Override
public void onNext(Long aLong) {
// do nothing
}
});
}