package com.mehmetakiftutuncu.eshotroid; import java.util.ArrayList; import android.annotation.SuppressLint; import android.app.SearchManager; import android.app.SearchableInfo; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import com.actionbarsherlock.app.SherlockActivity; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem.OnActionExpandListener; import com.actionbarsherlock.widget.SearchView; import com.handmark.pulltorefresh.library.PullToRefreshBase; import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; import com.handmark.pulltorefresh.library.PullToRefreshBase.OnPullEventListener; import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener; import com.handmark.pulltorefresh.library.PullToRefreshBase.State; import com.handmark.pulltorefresh.library.PullToRefreshListView; import com.mehmetakiftutuncu.eshotroid.adapters.BusListAdapter; import com.mehmetakiftutuncu.eshotroid.adapters.FavoritedBusGridAdapter; import com.mehmetakiftutuncu.eshotroid.database.MyDatabase; import com.mehmetakiftutuncu.eshotroid.model.Bus; import com.mehmetakiftutuncu.eshotroid.tasks.GetBussesPageTask; import com.mehmetakiftutuncu.eshotroid.utilities.Dialogs; import com.mehmetakiftutuncu.eshotroid.utilities.ExpandableHeightGridView; import com.mehmetakiftutuncu.eshotroid.utilities.MenuHandler; /** * Main activity of the application * * @author Mehmet Akif Tütüncü */ public class Main extends SherlockActivity { private PullToRefreshListView ptrList; private ProgressBar progressBar; private LinearLayout header; private BusListAdapter busListAdapter; private ArrayList<Bus> busses; private Menu moreMenu; /** * Tag for debugging */ public static final String LOG_TAG = "Eshotroid_Main"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); initialize(); loadBusses(); updateListHeader(); Dialogs.showMainHelpDialog(this, false); } /* When user initiates a search, Main activity will be called * with a new intent with Intent.ACTION_SEARCH as action * and an extra value which is query string */ @Override protected void onNewIntent(Intent intent) { setIntent(intent); if(Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); searchBusses(query); } } @Override public boolean onCreateOptionsMenu(Menu menu) { moreMenu = menu; final SearchView searchView = new SearchView(getSherlock().getActionBar().getThemedContext()); SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchableInfo info = searchManager.getSearchableInfo(getComponentName()); searchView.setSearchableInfo(info); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { /* Since the query will be performed when the text changes, * when submitted just request focus to hide keyboard * and then indicate that it was handled */ InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(searchView.getWindowToken(), 0); return true; } @Override public boolean onQueryTextChange(String query) { searchBusses(query); return true; } }); MenuItem searchItem = menu.add("item_search").setIcon(R.drawable.ic_search).setActionView(searchView); searchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW); searchItem.setOnActionExpandListener(new OnActionExpandListener() { @Override public boolean onMenuItemActionExpand(MenuItem item) { return true; } @Override public boolean onMenuItemActionCollapse(MenuItem item) { // SearchView is collapsing, list all the busses again. searchBusses(null); return true; } }); MenuInflater inflater = getSherlock().getMenuInflater(); inflater.inflate(R.menu.menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { // SearchView is collapsing, list all the busses again. case android.R.id.home: searchBusses(null); return true; default: MenuHandler.handle(this, item); return true; } } // Using onKeyUp instead of onKeyDown is working, otherwise the menu would just close itself after opening @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_MENU) { if (event.getAction() == KeyEvent.ACTION_UP && moreMenu != null) { moreMenu.performIdentifierAction(R.id.item_more, 0); return true; } } return super.onKeyUp(keyCode, event); } /** Initializes components */ @SuppressLint("NewApi") private void initialize() { ptrList = (PullToRefreshListView) findViewById(R.id.pullToRefreshListView_main_busses); ptrList.getLoadingLayoutProxy().setPullLabel(getString(R.string.pullToRefresh_pull)); ptrList.getLoadingLayoutProxy().setReleaseLabel(getString(R.string.pullToRefresh_release)); ptrList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapter, View view, int position, long id) { String number = ((TextView) view.findViewById(R.id.textView_busses_row_number)).getText().toString(); Intent intent = new Intent(Main.this, Times.class); intent.putExtra(Constants.BUS_NUMBER_EXTRA, Integer.parseInt(number)); startActivity(intent); } }); ptrList.setOnPullEventListener(new OnPullEventListener<ListView>() { @Override public void onPullEvent(PullToRefreshBase<ListView> refreshView, State state, Mode direction) { ptrList.getLoadingLayoutProxy().setRefreshingLabel(getString(R.string.pullToRefresh_refresh)); } }); ptrList.setOnRefreshListener(new OnRefreshListener<ListView>() { @Override public void onRefresh(PullToRefreshBase<ListView> refreshView) { downloadBusses(); } }); ptrList.setScrollingWhileRefreshingEnabled(false); ptrList.getRefreshableView().setTextFilterEnabled(true); header = (LinearLayout) getLayoutInflater().inflate(R.layout.busses_header, null); ptrList.getRefreshableView().addHeaderView(header, null, false); progressBar = (ProgressBar) findViewById(R.id.progressBar_main); } /** * Sets the list of busses * * @param busses New list of busses to be set */ public void setBussesList(ArrayList<Bus> busses) { this.busses = busses; busListAdapter = new BusListAdapter(this, busses); ptrList.setAdapter(busListAdapter); } /** * Gets the list of busses */ public ArrayList<Bus> getBussesList() { return busses; } /** * Gets the bus list adapter */ public BusListAdapter getBusListAdapter() { return busListAdapter; } /** Updates the list header and adds the favorited busses to the top */ public void updateListHeader() { ExpandableHeightGridView favoritedBussesGrid = (ExpandableHeightGridView) header.findViewById(R.id.gridView_favoritedBusses_grid); favoritedBussesGrid.setExpanded(true); ArrayList<Bus> favorited = new ArrayList<Bus>(); for(Bus i : busses) { if(i.isFavorited()) { favorited.add(i); } } if(favorited.size() > 0) { favoritedBussesGrid.setAdapter(new FavoritedBusGridAdapter(this, favorited)); header.findViewById(R.id.linearLayout_favoritedBusses).setVisibility(View.VISIBLE); } else { header.findViewById(R.id.linearLayout_favoritedBusses).setVisibility(View.GONE); } } /** Searches busses with the given query */ private void searchBusses(String query) { if(busListAdapter != null && busListAdapter.getFilter() != null) { busListAdapter.getFilter().filter(query); busListAdapter.notifyDataSetChanged(); } } /** Tries to download busses */ private void downloadBusses() { GetBussesPageTask task = new GetBussesPageTask(this, ptrList); task.execute(); } /** Reads busses from the database if possible, if not tries to download them. */ private void loadBusses() { /* Change the UI to waiting mode */ toggleMode(true); /* Read busses from the database */ MyDatabase db = new MyDatabase(this); db.openDB(); busses = db.get(); db.closeDB(); /* If no busses exist on the database */ if(busses.size() == 0) { Log.d(LOG_TAG, "Busses could not be found on the database!"); downloadBusses(); } else { /* Change the UI to ready mode */ toggleMode(false); /* Fill the list */ busListAdapter = new BusListAdapter(this, busses); ptrList.setAdapter(busListAdapter); } } /** * Toggles the UI mode to either ready or waiting (hides other content and shows a progress bar) * * @param isWaiting If true, mode will change to waiting, else it will change to ready mode */ public void toggleMode(boolean isWaiting) { if(isWaiting) { progressBar.setVisibility(View.VISIBLE); ptrList.getRefreshableView().setVisibility(View.GONE); } else { progressBar.setVisibility(View.GONE); ptrList.getRefreshableView().setVisibility(View.VISIBLE); } } }