/* * 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.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.FrameLayout; import android.widget.HeaderViewListAdapter; import android.widget.ListView; import android.widget.TextView; 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.CommandFailureResult; import com.ratebeer.android.api.CommandSuccessResult; import com.ratebeer.android.api.command.GetUserRatingsCommand; import com.ratebeer.android.api.command.GetUserRatingsCommand.UserRating; import com.ratebeer.android.gui.components.RateBeerFragment; import com.ratebeer.android.gui.components.helpers.ArrayAdapter; @EFragment(R.layout.fragment_userratings) @OptionsMenu({R.menu.refresh, R.menu.userratings}) public class UserRatingsFragment extends RateBeerFragment { private static final String DECIMAL_FORMATTER = "%.1f"; private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("M/d/yyyy"); @FragmentArg @InstanceState protected int userId; @InstanceState protected ArrayList<UserRating> ratings = null; @ViewById(R.id.empty) protected TextView emptyText; @ViewById(R.id.ratings) protected ListView ratingsView; private FrameLayout ratingsViewFooter; private boolean loading = false; private int pageNr = 1; private boolean preventLoadingOfMore = false; private int sortOrder = GetUserRatingsCommand.SORTBY_DATE; public UserRatingsFragment() { } @AfterViews public void init() { ratingsView.setOnScrollListener(onScrollListener); ratingsView.setOnItemClickListener(onItemSelected); // Manual inflating of the 'loading spinner' layout that is displayed as the list's footer view ratingsViewFooter = (FrameLayout) getActivity().getLayoutInflater().inflate(R.layout.endlesslist_footer, null); showLoading(false); ratingsView.addFooterView(ratingsViewFooter); if (ratings != null) { publishResults(ratings); } else { refreshRatings(); } } @OptionsItem(R.id.menu_sortby) protected void onSortRatings() { new UserRatingsSortDialog(this).show(getActivity().getSupportFragmentManager(), null); } private OnScrollListener onScrollListener = new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { boolean loadMore = totalItemCount > 0 && firstVisibleItem + visibleItemCount >= totalItemCount; if (loadMore && !loading && !preventLoadingOfMore) { pageNr++; loadRatings(); } } }; public void setSortOrder(int newSortOrder) { sortOrder = newSortOrder; refreshRatings(); } @OptionsItem(R.id.menu_refresh) protected void refreshRatings() { if (ratingsView.getAdapter() != null) { ratingsView.setAdapter(null); ratingsView.setVisibility(View.GONE); emptyText.setVisibility(View.GONE); } pageNr = 1; preventLoadingOfMore = false; loadRatings(); } private void loadRatings() { showLoading(true); execute(new GetUserRatingsCommand(getUser(), userId, pageNr, sortOrder)); } private OnItemClickListener onItemSelected = new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { UserRating item = ((UserRatingsAdapter) ((android.widget.HeaderViewListAdapter) ratingsView.getAdapter()) .getWrappedAdapter()).getItem(position); load(BeerViewFragment_.builder().beerId(item.beerId).beerName(item.beerName).build()); } }; @Override public void onTaskSuccessResult(CommandSuccessResult result) { if (result.getCommand().getMethod() == ApiMethod.GetUserRatings) { showLoading(false); publishResults(((GetUserRatingsCommand) result.getCommand()).getUserRatings()); } } private void publishResults(ArrayList<UserRating> result) { if (result.size() == 0) { // This was the end: don't load more now preventLoadingOfMore = true; return; } if (ratingsView.getAdapter() == null || (ratingsView.getAdapter() instanceof HeaderViewListAdapter && ((UserRatingsAdapter) ((android.widget.HeaderViewListAdapter) ratingsView.getAdapter()).getWrappedAdapter()) == null)) { ratingsView.setAdapter(new UserRatingsAdapter(getActivity(), result)); this.ratings = result; } else { ((UserRatingsAdapter) ((android.widget.HeaderViewListAdapter) ratingsView.getAdapter()).getWrappedAdapter()) .addAll(result); this.ratings.addAll(result); } ratingsView.setVisibility(result.size() == 0 ? View.GONE : View.VISIBLE); emptyText.setVisibility(result.size() == 0 ? View.VISIBLE : View.GONE); } private void showLoading(boolean loading) { this.loading = loading; ratingsViewFooter.setLayoutParams(new AbsListView.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, loading ? FrameLayout.LayoutParams.WRAP_CONTENT : 0)); } @Override public void onTaskFailureResult(CommandFailureResult result) { if (result.getCommand().getMethod() == ApiMethod.GetUserRatings) { showLoading(false); } publishException(emptyText, result.getException()); } private class UserRatingsAdapter extends ArrayAdapter<UserRating> { public UserRatingsAdapter(Context context, List<UserRating> objects) { super(context, objects); } @Override public View getView(int position, View convertView, ViewGroup parent) { // Get the right view, using a ViewHolder ViewHolder holder; if (convertView == null || convertView.getTag() == null) { convertView = getActivity().getLayoutInflater().inflate(R.layout.list_item_userrating, null); holder = new ViewHolder(); holder.beer = (TextView) convertView.findViewById(R.id.beer); holder.brewer = (TextView) convertView.findViewById(R.id.brewer); holder.style = (TextView) convertView.findViewById(R.id.style); holder.score = (TextView) convertView.findViewById(R.id.score); holder.myrating = (TextView) convertView.findViewById(R.id.myrating); holder.date = (TextView) convertView.findViewById(R.id.date); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // Bind the data UserRating item = getItem(position); holder.beer.setText(item.beerName); holder.brewer.setText(item.brewerName); holder.style.setText(item.styleName); holder.score.setText(getString(R.string.myratings_avg, String.format(DECIMAL_FORMATTER, item.score))); holder.myrating.setText(String.format(DECIMAL_FORMATTER, item.myRating)); holder.date.setText(DATE_FORMATTER.format(item.date)); return convertView; } } protected static class ViewHolder { TextView beer, brewer, style, score, myrating, date; } }