package info.papdt.express.helper.ui; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.support.v4.app.Fragment; import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewPager; import android.support.v7.widget.LinearLayoutManager; import android.text.TextUtils; import android.view.ContextThemeWrapper; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.animation.AlphaAnimation; import android.view.animation.DecelerateInterpolator; import android.widget.Toast; import com.afollestad.materialdialogs.MaterialDialog; import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView; import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks; import com.github.ksoichiro.android.observablescrollview.ScrollState; import com.github.ksoichiro.android.observablescrollview.ScrollUtils; import com.github.ksoichiro.android.observablescrollview.Scrollable; import com.melnykov.fab.FloatingActionButton; import com.nineoldandroids.view.ViewHelper; import com.nineoldandroids.view.ViewPropertyAnimator; import com.quinny898.library.persistentsearch.SearchBox; import org.json.JSONException; import java.io.IOException; import java.util.ArrayList; import info.papdt.express.helper.R; import info.papdt.express.helper.api.KuaiDi100Helper; import info.papdt.express.helper.dao.ExpressDatabase; import info.papdt.express.helper.support.CrashHandler; import info.papdt.express.helper.support.Settings; import info.papdt.express.helper.support.Utility; import info.papdt.express.helper.ui.adapter.CompanyListRecyclerAdapter; import info.papdt.express.helper.ui.adapter.HomePagerAdapter; import info.papdt.express.helper.ui.common.MyRecyclerViewAdapter; import info.papdt.express.helper.ui.fragment.BaseHomeFragment; import info.papdt.express.helper.view.SlidingTabLayout; public class MainActivity extends AbsActivity implements ObservableScrollViewCallbacks { public ExpressDatabase mExpressDB; private View mHeaderView; private int mBaseTranslationY; private ViewPager mPager; private SlidingTabLayout mSlidingTab; private HomePagerAdapter mPagerAdapter; private FloatingActionButton mFAB; private SearchBox mSearchBox; private View mCompanyListPage, mCompanyListPageBackground; private ObservableRecyclerView mCompanyList; private CompanyListRecyclerAdapter mCompanyListAdapter; public static final int REQUEST_ADD = 100, RESULT_ADD_FINISH = 100, REQUEST_DETAILS = 101, RESULT_HAS_CHANGED = 101; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); int selectedTab = mSets.getInt(Settings.STATE_SELECTED_TAB, 0); /** Init crash handler */ CrashHandler.init(getApplicationContext()); CrashHandler.register(); setSwipeBackEnable(false); /** Init Database */ mExpressDB = new ExpressDatabase(getApplicationContext()); refreshDatabase(false); /** Init ViewPager */ mPagerAdapter = new HomePagerAdapter(getApplicationContext(), getSupportFragmentManager()); mPager.setAdapter(mPagerAdapter); mPager.setCurrentItem(selectedTab, false); mSlidingTab.setViewPager(mPager); } @Override public void onStop() { mSets.putInt(Settings.STATE_SELECTED_TAB, mPager.getCurrentItem()); super.onStop(); } public void refreshDatabase(boolean pullNewData) { mExpressDB.init(); if (pullNewData) { mExpressDB.pullNewDataFromNetwork(false); try { mExpressDB.save(); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } } runOnUiThread(new Runnable() { @Override public void run() { try { mPagerAdapter.notifyDataSetChanged(); } catch (Exception e) { } } }); } @Override protected void setUpViews() { View statusHeaderView1 = findViewById(R.id.statusHeaderView1); statusHeaderView1.getLayoutParams().height = statusBarHeight; mSearchBox = (SearchBox) findViewById(R.id.searchBox); mCompanyListPage = findViewById(R.id.company_list_page); mCompanyListPageBackground = findViewById(R.id.company_list_page_background); mCompanyList = (ObservableRecyclerView) mCompanyListPage.findViewById(R.id.recycler_view); mSearchBox.setLogoText(""); mSearchBox.setHintText(getString(R.string.search_hint_company)); mCompanyList.setLayoutManager(new LinearLayoutManager(this)); mCompanyList.setHasFixedSize(true); mHeaderView = findViewById(R.id.header); ViewCompat.setElevation(mHeaderView, getResources().getDimension(R.dimen.toolbar_elevation)); mPager = (ViewPager) findViewById(R.id.pager); /** Set up SlidingTabLayout */ mSlidingTab = (SlidingTabLayout) findViewById(R.id.sliding_tabs); mSlidingTab.setCustomTabView(R.layout.tab_indicator, android.R.id.text1); mSlidingTab.setSelectedIndicatorColors(getResources().getColor(android.R.color.white)); mSlidingTab.setDistributeEvenly(true); mSlidingTab.setOnTabItemClickListener(new SlidingTabLayout.OnTabItemClickListener() { @Override public void onTabItemClick(int pos) { BaseHomeFragment fragment = (BaseHomeFragment) mPagerAdapter.getItemAt(pos); try { fragment.scrollToTopItem(); } catch (Exception e) { } } }); // When the page is selected, other fragments' scrollY should be adjusted // according to the toolbar status(shown/hidden) mSlidingTab.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int i, float v, int i2) { } @Override public void onPageSelected(int i) { propagateToolbarState(toolbarIsShown()); } @Override public void onPageScrollStateChanged(int i) { } }); /** Set up FloatingActionButton */ mFAB = (FloatingActionButton) findViewById(R.id.fab); mFAB.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { AddActivity.launch(MainActivity.this, mFAB); } }); } public void openCompanyList() { mCompanyListPage.setVisibility(View.VISIBLE); AlphaAnimation anim = new AlphaAnimation(0f, 1f); anim.setInterpolator(new DecelerateInterpolator()); anim.setFillAfter(true); anim.setDuration(250); mCompanyListPageBackground.startAnimation(anim); mCompanyList.startAnimation(anim); mSearchBox.revealFromMenuItem(R.id.action_select_company, this); mSearchBox.setSearchListener(new SearchBox.SearchListener() { @Override public void onSearchOpened() { new SearchCompanyTask().execute(); } @Override public void onSearchCleared() { } @Override public void onSearchClosed() { closeCompanyList(); } @Override public void onSearchTermChanged() { new SearchCompanyTask().execute(mSearchBox.getSearchText()); } @Override public void onSearch(String result) { } }); } public void closeCompanyList() { mSearchBox.hideCircularly(this); AlphaAnimation anim = new AlphaAnimation(1f, 0f); anim.setInterpolator(new DecelerateInterpolator()); anim.setFillAfter(true); anim.setDuration(250); mCompanyListPageBackground.startAnimation(anim); mCompanyList.startAnimation(anim); new Handler().postDelayed(new Runnable() { @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { mCompanyListPage.setVisibility(View.GONE); } }); } }, 250); } private void showDonateDialog() { View v = View.inflate( new ContextThemeWrapper( getApplicationContext(), R.style.Theme_AppCompat_Light_Dialog ), R.layout.dialog_donate, null ); new MaterialDialog.Builder(this) .title(R.string.item_donate) .customView(v, false) .negativeText(android.R.string.ok) .show(); } @Override public void onBackPressed() { if (mSearchBox.isSearchOpened()) { mSearchBox.toggleSearch(); } else { super.onBackPressed(); } } @Override public void onScrollChanged(int scrollY, boolean firstScroll, boolean dragging) { if (dragging) { int toolbarHeight = mToolbar.getHeight(); float currentHeaderTranslationY = ViewHelper.getTranslationY(mHeaderView); if (firstScroll) { if (-toolbarHeight < currentHeaderTranslationY) { mBaseTranslationY = scrollY; } } float headerTranslationY = ScrollUtils.getFloat(-(scrollY - mBaseTranslationY), -toolbarHeight, 0); ViewPropertyAnimator.animate(mHeaderView).cancel(); ViewHelper.setTranslationY(mHeaderView, headerTranslationY); } } @Override public void onDownMotionEvent() { } @Override public void onUpOrCancelMotionEvent(ScrollState scrollState) { mBaseTranslationY = 0; Fragment fragment = getCurrentFragment(); if (fragment == null) { return; } View view = fragment.getView(); if (view == null) { return; } // ObservableXxxViews have same API // but currently they don't have any common interfaces. adjustToolbar(scrollState, view); } private Fragment getCurrentFragment() { return mPagerAdapter.getItemAt(mPager.getCurrentItem()); } private void adjustToolbar(ScrollState scrollState, View view) { int toolbarHeight = mToolbar.getHeight(); final Scrollable scrollView = (Scrollable) view.findViewById(R.id.scroll); if (scrollView == null) { return; } int scrollY = scrollView.getCurrentScrollY(); if (scrollState == ScrollState.DOWN) { showToolbar(); } else if (scrollState == ScrollState.UP) { if (toolbarHeight <= scrollY) { hideToolbar(); } else { showToolbar(); } } else { // Even if onScrollChanged occurs without scrollY changing, toolbar should be adjusted if (toolbarIsShown() || toolbarIsHidden()) { // Toolbar is completely moved, so just keep its state // and propagate it to other pages propagateToolbarState(toolbarIsShown()); } else { // Toolbar is moving but doesn't know which to move: // you can change this to hideToolbar() showToolbar(); } } } private void propagateToolbarState(boolean isShown) { int toolbarHeight = mToolbar.getHeight(); // Set scrollY for the fragments that are not created yet mPagerAdapter.setScrollY(isShown ? 0 : toolbarHeight); // Set scrollY for the active fragments for (int i = 0; i < mPagerAdapter.getCount(); i++) { // Skip current item if (i == mPager.getCurrentItem()) { continue; } // Skip destroyed or not created item Fragment f = mPagerAdapter.getItemAt(i); if (f == null) { continue; } View view = f.getView(); if (view == null) { continue; } propagateToolbarState(isShown, view, toolbarHeight); } } private void propagateToolbarState(boolean isShown, View view, int toolbarHeight) { Scrollable scrollView = (Scrollable) view.findViewById(R.id.scroll); if (scrollView == null) { return; } if (isShown) { // Scroll up if (0 < scrollView.getCurrentScrollY()) { scrollView.scrollVerticallyTo(0); } } else { // Scroll down (to hide padding) if (scrollView.getCurrentScrollY() < toolbarHeight) { scrollView.scrollVerticallyTo(toolbarHeight); } } } private boolean toolbarIsShown() { return ViewHelper.getTranslationY(mHeaderView) == 0; } private boolean toolbarIsHidden() { return ViewHelper.getTranslationY(mHeaderView) == - mToolbar.getHeight(); } private void showToolbar() { float headerTranslationY = ViewHelper.getTranslationY(mHeaderView); if (headerTranslationY != 0) { ViewPropertyAnimator.animate(mHeaderView).cancel(); ViewPropertyAnimator.animate(mHeaderView).translationY(0).setDuration(200).start(); } propagateToolbarState(true); } private void hideToolbar() { float headerTranslationY = ViewHelper.getTranslationY(mHeaderView); int toolbarHeight = mToolbar.getHeight(); if (headerTranslationY != -toolbarHeight) { ViewPropertyAnimator.animate(mHeaderView).cancel(); ViewPropertyAnimator.animate(mHeaderView).translationY(-toolbarHeight).setDuration(200).start(); } propagateToolbarState(false); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { switch (requestCode) { case REQUEST_ADD: if (resultCode == RESULT_ADD_FINISH) { String jsonStr = intent.getStringExtra("result"); String name = intent.getStringExtra("name"); mExpressDB.addExpress(jsonStr, name); try { mExpressDB.save(); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } mPagerAdapter.notifyDataSetChanged(); } break; case REQUEST_DETAILS: if (resultCode == RESULT_HAS_CHANGED) { mPagerAdapter.notifyDataSetChanged(); } break; } } @Override protected void onPause() { super.onPause(); try { mExpressDB.save(); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } } @Override public boolean onPrepareOptionsMenu(Menu menu) { menu.clear(); getMenuInflater().inflate(R.menu.main_menu, menu); return super.onPrepareOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_settings) { SettingsActivity.launchActivity(this, SettingsActivity.FLAG_MAIN); return true; } if (id == R.id.action_select_company) { openCompanyList(); return true; } if (id == R.id.action_donate) { showDonateDialog(); return true; } if (id == R.id.action_add) { AddActivity.launch(MainActivity.this, mFAB); return true; } if (id == R.id.action_manual_refresh) { Fragment fragment = mPagerAdapter.getItemAt(mPager.getCurrentItem()); if (fragment instanceof BaseHomeFragment) { ((BaseHomeFragment) fragment).mHandler.sendEmptyMessage(BaseHomeFragment.FLAG_REFRESH_LIST); } Toast.makeText( getApplicationContext(), R.string.toast_pull_to_refresh_tips, Toast.LENGTH_LONG ).show(); return true; } return super.onOptionsItemSelected(item); } public void mic(View v) { if (Utility.isApplicationAvailable(getApplicationContext(), "com.mokee.assist")) { Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("com.mokee.assist"); startActivity(LaunchIntent); } else { Toast.makeText( getApplicationContext(), R.string.toast_mic_unsupported, Toast.LENGTH_SHORT ).show(); } } public class SearchCompanyTask extends AsyncTask<String, Void, ArrayList<KuaiDi100Helper.CompanyInfo.Company>> { @Override protected ArrayList<KuaiDi100Helper.CompanyInfo.Company> doInBackground(String... params) { if (params.length > 0) { return KuaiDi100Helper.searchCompany(params [0]); } else { return KuaiDi100Helper.CompanyInfo.info; } } @Override protected void onPostExecute(ArrayList<KuaiDi100Helper.CompanyInfo.Company> result) { if (result != null) { mCompanyListAdapter = new CompanyListRecyclerAdapter(result); mCompanyList.setAdapter(mCompanyListAdapter); mCompanyListAdapter.setOnItemClickListener(new MyRecyclerViewAdapter.OnItemClickListener() { @Override public void onItemClicked(int position) { String phone = mCompanyListAdapter.getItem(position).phone; if (phone != null && phone != "null" && !TextUtils.isEmpty(phone)) { Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse("tel:" + phone)); startActivity(intent); } else { Toast.makeText( getApplicationContext(), R.string.toast_phone_is_not_exist, Toast.LENGTH_SHORT ).show(); } } }); } } } }