Java tutorial
/* This file is part of RateBeer For Android. RateBeer for Android is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. RateBeer for Android is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with RateBeer for Android. If not, see <http://www.gnu.org/licenses/>. */ package com.ratebeer.android.gui.fragments; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.text.DateFormat; import java.util.ArrayList; import java.util.List; import java.util.Locale; import android.content.Context; import android.content.Intent; import android.location.Location; import android.net.Uri; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.Button; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import com.google.android.gms.maps.MapView; import com.google.android.gms.maps.model.BitmapDescriptorFactory; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; import com.googlecode.androidannotations.annotations.AfterViews; import com.googlecode.androidannotations.annotations.EFragment; import com.googlecode.androidannotations.annotations.FragmentArg; import com.googlecode.androidannotations.annotations.InstanceState; import com.googlecode.androidannotations.annotations.OptionsItem; import com.googlecode.androidannotations.annotations.OptionsMenu; import com.googlecode.androidannotations.annotations.ViewById; import com.ratebeer.android.R; import com.ratebeer.android.api.ApiMethod; import com.ratebeer.android.api.CommandSuccessResult; import com.ratebeer.android.api.HttpHelper; import com.ratebeer.android.api.command.CheckInCommand; import com.ratebeer.android.api.command.GetAvailableBeersCommand; import com.ratebeer.android.api.command.GetAvailableBeersCommand.AvailableBeer; import com.ratebeer.android.api.command.GetCheckinsCommand; import com.ratebeer.android.api.command.GetCheckinsCommand.CheckedInUser; import com.ratebeer.android.api.command.GetPlaceDetailsCommand; import com.ratebeer.android.api.command.GetPlacesAroundCommand.Place; import com.ratebeer.android.app.location.LocationUtils; import com.ratebeer.android.gui.components.RateBeerMapFragment; import com.ratebeer.android.gui.components.helpers.ActivityUtil; import com.ratebeer.android.gui.components.helpers.ArrayAdapter; import com.viewpagerindicator.TabPageIndicator; import de.neofonie.mobile.app.android.widget.crouton.Crouton; import de.neofonie.mobile.app.android.widget.crouton.Style; @EFragment(R.layout.fragment_placeview) @OptionsMenu({ R.menu.refresh, R.menu.share }) public class PlaceViewFragment extends RateBeerMapFragment { @FragmentArg @InstanceState protected int placeId; @FragmentArg @InstanceState protected Place place = null; @FragmentArg @InstanceState protected Location currentLocation = null; @InstanceState protected ArrayList<CheckedInUser> checkins = null; @InstanceState protected ArrayList<AvailableBeer> availableBeers = null; @ViewById protected ViewPager pager; @ViewById protected TabPageIndicator titles; @ViewById(R.id.name) protected TextView nameText; @ViewById(R.id.rating) protected TextView ratingText; private TextView typeText; private Button addressText, phoneText, checkinhereButton; private ListView checkinsView; private ListView availableBeersView; private TextView availableBeersEmpty; public PlaceViewFragment() { } @AfterViews public void init() { pager.setAdapter(new PlacePagerAdapter()); titles.setViewPager(pager); if (checkins != null && availableBeers != null && place != null) { publishDetails(place); publishCheckins(checkins); publishAvailableBeers(availableBeers); } else if (place != null) { // Use the already known details placeId = place.placeID; publishDetails(place); refreshCheckins(); refreshAvailableBeers(); } else { // Retrieve the details too refreshDetails(); refreshCheckins(); refreshAvailableBeers(); } } @OptionsItem(R.id.menu_refresh) protected void onRefresh() { refreshDetails(); refreshCheckins(); refreshAvailableBeers(); } @OptionsItem(R.id.menu_share) protected void onShare() { if (place != null) { // Start a share intent for this event Intent s = new Intent(Intent.ACTION_SEND); s.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); s.setType("text/plain"); s.putExtra(Intent.EXTRA_TEXT, getString(R.string.places_share, place.placeName, place.placeID)); startActivity(Intent.createChooser(s, getString(R.string.places_shareplace))); } } private void refreshDetails() { execute(new GetPlaceDetailsCommand(getUser(), placeId)); } private void refreshCheckins() { execute(new GetCheckinsCommand(getUser(), placeId)); } private void refreshAvailableBeers() { execute(new GetAvailableBeersCommand(getUser(), placeId)); availableBeersEmpty.setText(R.string.details_noavailability); } private OnClickListener onAddressClick = new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); try { intent.setData(Uri.parse("geo:" + place.latitude + "," + place.longitude + "?q=" + URLEncoder.encode(place.placeName, HttpHelper.UTF8))); } catch (UnsupportedEncodingException e) { // UTF-8 always exists } startActivity(intent); } }; private OnClickListener onPhoneClick = new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_DIAL); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); intent.setData(Uri .parse("tel:" + place.phoneNumber.replace("-", "").replace("+", "").replace(" ", "").trim())); startActivity(intent); } }; private void onCheckinClick(int userId, String userName) { load(UserViewFragment_.builder().userId(userId).userName(userName).build()); } private void onAvailableBeerClick(int beerId, String beerName) { load(BeerViewFragment_.builder().beerId(beerId).beerName(beerName).build()); } @Override public void onTaskSuccessResult(CommandSuccessResult result) { if (result.getCommand().getMethod() == ApiMethod.GetPlaceDetails) { publishDetails(((GetPlaceDetailsCommand) result.getCommand()).getDetails()); } else if (result.getCommand().getMethod() == ApiMethod.GetCheckins) { publishCheckins(((GetCheckinsCommand) result.getCommand()).getCheckins()); } else if (result.getCommand().getMethod() == ApiMethod.CheckIn) { Crouton.makeText(getActivity(), R.string.places_checkedinnow, Style.CONFIRM).show(); refreshCheckins(); } else if (result.getCommand().getMethod() == ApiMethod.GetAvailableBeers) { publishAvailableBeers(((GetAvailableBeersCommand) result.getCommand()).getAvailableBeers()); } } private OnClickListener onCheckInClick = new OnClickListener() { @Override public void onClick(View v) { // Check in to this place execute(new CheckInCommand(getUser(), placeId)); } }; private void publishDetails(Place details) { this.place = details; if (details == null) { return; } // Show details setDetails(details); } private void publishCheckins(ArrayList<CheckedInUser> checkins) { this.checkins = checkins; if (checkinsView.getAdapter() == null) { checkinsView.setAdapter(new CheckinsAdapter(getActivity(), checkins)); } else { ((CheckinsAdapter) checkinsView.getAdapter()).replace(checkins); } } private void publishAvailableBeers(ArrayList<AvailableBeer> availableBeers) { this.availableBeers = availableBeers; if (availableBeersView.getAdapter() == null) { availableBeersView.setAdapter(new AvailableBeersAdapter(getActivity(), availableBeers)); } else { ((AvailableBeersAdapter) availableBeersView.getAdapter()).replace(availableBeers); } } private void setDetails(Place details) { nameText.setText(place.placeName); typeText.setText(PlacesFragment.getPlaceTypeName(getActivity(), place.placeType)); ratingText.setText(place.avgRating == -1 ? "?" : Integer.toString(place.avgRating)); String distanceText = LocationUtils.getPlaceDistance(getSettings(), getResources(), place, currentLocation); addressText.setText(place.address + "\n" + place.city + (place.distance == -1D || distanceText == null ? "" : "\n" + distanceText)); phoneText.setText(place.phoneNumber); if (getMap() != null) { LocationUtils.initGoogleMap(getMap(), place.latitude, place.longitude); getMap().addMarker(new MarkerOptions().position(new LatLng(place.latitude, place.longitude)) .title(place.placeName).snippet(LocationUtils.getPlaceSnippet(getActivity(), place)) .icon(BitmapDescriptorFactory.defaultMarker(LocationUtils.getPlaceColour(place)))); } // Make fields visible too ratingText.setVisibility(View.VISIBLE); addressText.setVisibility(View.VISIBLE); phoneText.setVisibility(View.VISIBLE); checkinhereButton.setVisibility(View.VISIBLE); } private class CheckinsAdapter extends ArrayAdapter<CheckedInUser> { private OnClickListener onRowClick = new OnClickListener() { @Override public void onClick(View v) { onCheckinClick((Integer) v.findViewById(R.id.user).getTag(), ((TextView) v.findViewById(R.id.user)).getText().toString()); } }; public CheckinsAdapter(Context context, List<CheckedInUser> objects) { super(context, objects); } @Override public View getView(int position, View convertView, ViewGroup parent) { // Get the right view, using a ViewHolder CheckinViewHolder holder; if (convertView == null) { convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_checkedinuser, null); ActivityUtil.makeListItemClickable(convertView, onRowClick); holder = new CheckinViewHolder(); holder.name = (TextView) convertView.findViewById(R.id.user); convertView.setTag(holder); } else { holder = (CheckinViewHolder) convertView.getTag(); } // Bind the data CheckedInUser item = getItem(position); holder.name.setTag(item.userID); holder.name.setText(item.userName); return convertView; } } protected static class CheckinViewHolder { TextView name; } private class AvailableBeersAdapter extends ArrayAdapter<AvailableBeer> { private final DateFormat dateFormat; private OnClickListener onRowClick = new OnClickListener() { @Override public void onClick(View v) { onAvailableBeerClick((Integer) v.findViewById(R.id.beer).getTag(), ((TextView) v.findViewById(R.id.beer)).getText().toString()); } }; public AvailableBeersAdapter(Context context, List<AvailableBeer> objects) { super(context, objects); this.dateFormat = android.text.format.DateFormat.getDateFormat(getActivity()); } @Override public View getView(int position, View convertView, ViewGroup parent) { // Get the right view, using a ViewHolder AvailableBeerViewHolder holder; if (convertView == null) { convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_availablebeer, null); ActivityUtil.makeListItemClickable(convertView, onRowClick); holder = new AvailableBeerViewHolder(); holder.score = (TextView) convertView.findViewById(R.id.score); holder.beer = (TextView) convertView.findViewById(R.id.beer); holder.timerecorded = (TextView) convertView.findViewById(R.id.timerecorded); convertView.setTag(holder); } else { holder = (AvailableBeerViewHolder) convertView.getTag(); } // Bind the data AvailableBeer item = getItem(position); holder.beer.setTag(item.beerId); holder.beer.setText(item.beerName); holder.score.setText(item.averageRating == -1 ? "?" : Integer.toString(item.averageRating)); if (item.timeEntered != null) { holder.timerecorded .setText(getString(R.string.places_enteredat, dateFormat.format(item.timeEntered))); } else { holder.timerecorded.setText(""); } return convertView; } } protected static class AvailableBeerViewHolder { TextView score, beer, timerecorded; } private class PlacePagerAdapter extends PagerAdapter { private View pagerDetailsView; private View pagerCheckinsView; private FrameLayout pagerAvailableBeersFrame; public PlacePagerAdapter() { LayoutInflater inflater = getActivity().getLayoutInflater(); pagerDetailsView = (LinearLayout) inflater.inflate(R.layout.fragment_placedetails, null); pagerCheckinsView = (LinearLayout) inflater.inflate(R.layout.fragment_placecheckins, null); pagerAvailableBeersFrame = (FrameLayout) inflater.inflate(R.layout.fragment_searchlist, null); availableBeersEmpty = (TextView) pagerAvailableBeersFrame.findViewById(R.id.empty); availableBeersView = (ListView) pagerAvailableBeersFrame.findViewById(R.id.list); availableBeersView.setEmptyView(availableBeersEmpty); checkinsView = (ListView) pagerCheckinsView.findViewById(R.id.list); checkinhereButton = (Button) pagerCheckinsView.findViewById(R.id.checkinhere); checkinhereButton.setOnClickListener(onCheckInClick); typeText = (TextView) pagerDetailsView.findViewById(R.id.type); addressText = (Button) pagerDetailsView.findViewById(R.id.address); phoneText = (Button) pagerDetailsView.findViewById(R.id.phone); setMapView((MapView) pagerDetailsView.findViewById(R.id.map_place)); addressText.setOnClickListener(onAddressClick); phoneText.setOnClickListener(onPhoneClick); } @Override public int getCount() { return 3; } @Override public CharSequence getPageTitle(int position) { switch (position) { case 0: return getActivity().getString(R.string.app_details).toUpperCase(Locale.getDefault()); case 1: return getActivity().getString(R.string.places_checkins).toUpperCase(Locale.getDefault()); case 2: return getActivity().getString(R.string.places_availablebeers).toUpperCase(Locale.getDefault()); } return null; } @Override public Object instantiateItem(View container, int position) { switch (position) { case 0: ((ViewPager) container).addView(pagerDetailsView, 0); return pagerDetailsView; case 1: ((ViewPager) container).addView(pagerCheckinsView, 0); return pagerCheckinsView; case 2: ((ViewPager) container).addView(pagerAvailableBeersFrame, 0); return pagerAvailableBeersFrame; } return null; } @Override public void destroyItem(View container, int position, Object object) { ((ViewPager) container).removeView((View) object); } @Override public boolean isViewFromObject(View view, Object object) { return view == (View) object; } } }