aboutsummaryrefslogtreecommitdiff
path: root/WordPress/src/main/java/org/wordpress/android/ui/themes/ThemeBrowserFragment.java
diff options
context:
space:
mode:
Diffstat (limited to 'WordPress/src/main/java/org/wordpress/android/ui/themes/ThemeBrowserFragment.java')
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/themes/ThemeBrowserFragment.java383
1 files changed, 383 insertions, 0 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/themes/ThemeBrowserFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/themes/ThemeBrowserFragment.java
new file mode 100644
index 000000000..10df605cc
--- /dev/null
+++ b/WordPress/src/main/java/org/wordpress/android/ui/themes/ThemeBrowserFragment.java
@@ -0,0 +1,383 @@
+package org.wordpress.android.ui.themes;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.AbsListView.RecyclerListener;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.ImageLoader.ImageContainer;
+import com.android.volley.toolbox.ImageLoader.ImageListener;
+import com.android.volley.toolbox.NetworkImageView;
+
+import org.wordpress.android.R;
+import org.wordpress.android.WordPress;
+import org.wordpress.android.models.Theme;
+import org.wordpress.android.util.NetworkUtils;
+import org.wordpress.android.util.helpers.SwipeToRefreshHelper;
+import org.wordpress.android.util.helpers.SwipeToRefreshHelper.RefreshListener;
+import org.wordpress.android.util.widgets.CustomSwipeRefreshLayout;
+import org.wordpress.android.widgets.HeaderGridView;
+
+/**
+ * A fragment display the themes on a grid view.
+ */
+public class ThemeBrowserFragment extends Fragment implements RecyclerListener, AdapterView.OnItemSelectedListener, AbsListView.OnScrollListener {
+ public interface ThemeBrowserFragmentCallback {
+ void onActivateSelected(String themeId);
+ void onTryAndCustomizeSelected(String themeId);
+ void onViewSelected(String themeId);
+ void onDetailsSelected(String themeId);
+ void onSupportSelected(String themeId);
+ void onSearchClicked();
+ }
+
+ protected static final String BUNDLE_PAGE = "BUNDLE_PAGE";
+ protected static final int THEME_FILTER_ALL_INDEX = 0;
+ protected static final int THEME_FILTER_FREE_INDEX = 1;
+ protected static final int THEME_FILTER_PREMIUM_INDEX = 2;
+
+ protected SwipeToRefreshHelper mSwipeToRefreshHelper;
+ protected ThemeBrowserActivity mThemeBrowserActivity;
+ private String mCurrentThemeId;
+ private HeaderGridView mGridView;
+ private RelativeLayout mEmptyView;
+ private TextView mNoResultText;
+ private TextView mCurrentThemeTextView;
+ private ThemeBrowserAdapter mAdapter;
+ private Spinner mSpinner;
+ private ThemeBrowserFragmentCallback mCallback;
+ private int mPage = 1;
+ private boolean mShouldRefreshOnStart;
+ private TextView mEmptyTextView;
+ private ProgressBar mProgressBar;
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+
+ try {
+ mCallback = (ThemeBrowserFragmentCallback) activity;
+ mThemeBrowserActivity = (ThemeBrowserActivity) activity;
+ } catch (ClassCastException e) {
+ throw new ClassCastException(activity.toString() + " must implement ThemeBrowserFragmentCallback");
+ }
+ }
+
+ @Override
+ public void onDetach() {
+ super.onDetach();
+ mCallback = null;
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.theme_browser_fragment, container, false);
+
+ setRetainInstance(true);
+ mNoResultText = (TextView) view.findViewById(R.id.theme_no_search_result_text);
+ mEmptyTextView = (TextView) view.findViewById(R.id.text_empty);
+ mEmptyView = (RelativeLayout) view.findViewById(R.id.empty_view);
+ mProgressBar = (ProgressBar) view.findViewById(R.id.theme_loading_progress_bar);
+
+ configureGridView(inflater, view);
+ configureSwipeToRefresh(view);
+
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ if (this instanceof ThemeSearchFragment) {
+ mThemeBrowserActivity.setThemeSearchFragment((ThemeSearchFragment) this);
+ } else {
+ mThemeBrowserActivity.setThemeBrowserFragment(this);
+ }
+ Cursor cursor = fetchThemes(getSpinnerPosition());
+
+ if (cursor == null) {
+ return;
+ }
+
+ mAdapter = new ThemeBrowserAdapter(mThemeBrowserActivity, cursor, false, mCallback);
+ setEmptyViewVisible(mAdapter.getCount() == 0);
+ mGridView.setAdapter(mAdapter);
+ restoreState(savedInstanceState);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ mThemeBrowserActivity.fetchCurrentTheme();
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ if (mGridView != null) {
+ outState.putInt(BUNDLE_PAGE, mPage);
+ }
+ }
+
+ public TextView getEmptyTextView() {
+ return mEmptyTextView;
+ }
+
+ public TextView getCurrentThemeTextView() {
+ return mCurrentThemeTextView;
+ }
+
+ public void setCurrentThemeId(String currentThemeId) {
+ mCurrentThemeId = currentThemeId;
+ }
+
+ public int getPage() {
+ return mPage;
+ }
+
+ protected void addHeaderViews(LayoutInflater inflater) {
+ addMainHeader(inflater);
+ configureAndAddSearchHeader(inflater);
+ }
+
+ protected void configureSwipeToRefresh(View view) {
+ mSwipeToRefreshHelper = new SwipeToRefreshHelper(mThemeBrowserActivity, (CustomSwipeRefreshLayout) view.findViewById(
+ R.id.ptr_layout), new RefreshListener() {
+ @Override
+ public void onRefreshStarted() {
+ if (!isAdded()) {
+ return;
+ }
+ if (!NetworkUtils.checkConnection(mThemeBrowserActivity)) {
+ mSwipeToRefreshHelper.setRefreshing(false);
+ mEmptyTextView.setText(R.string.no_network_title);
+ return;
+ }
+ mThemeBrowserActivity.fetchThemes();
+ }
+ });
+ mSwipeToRefreshHelper.setRefreshing(mShouldRefreshOnStart);
+ }
+
+ private void configureGridView(LayoutInflater inflater, View view) {
+ mGridView = (HeaderGridView) view.findViewById(R.id.theme_listview);
+ addHeaderViews(inflater);
+ mGridView.setRecyclerListener(this);
+ mGridView.setOnScrollListener(this);
+ }
+
+ private void addMainHeader(LayoutInflater inflater) {
+ View header = inflater.inflate(R.layout.theme_grid_cardview_header, null);
+ mCurrentThemeTextView = (TextView) header.findViewById(R.id.header_theme_text);
+
+ setThemeNameIfAlreadyAvailable();
+ mThemeBrowserActivity.fetchCurrentTheme();
+ LinearLayout customize = (LinearLayout) header.findViewById(R.id.customize);
+ customize.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mCallback.onTryAndCustomizeSelected(mCurrentThemeId);
+ }
+ });
+
+ LinearLayout details = (LinearLayout) header.findViewById(R.id.details);
+ details.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mCallback.onDetailsSelected(mCurrentThemeId);
+ }
+ });
+
+ LinearLayout support = (LinearLayout) header.findViewById(R.id.support);
+ support.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mCallback.onSupportSelected(mCurrentThemeId);
+ }
+ });
+
+ mGridView.addHeaderView(header);
+ }
+
+ private void setThemeNameIfAlreadyAvailable() {
+ Theme currentTheme = mThemeBrowserActivity.getCurrentTheme();
+ if (currentTheme != null) {
+ mCurrentThemeTextView.setText(currentTheme.getName());
+ }
+ }
+
+ public void setRefreshing(boolean refreshing) {
+ mShouldRefreshOnStart = refreshing;
+ if (mSwipeToRefreshHelper != null) {
+ mSwipeToRefreshHelper.setRefreshing(refreshing);
+ if (!refreshing) {
+ refreshView(getSpinnerPosition());
+ }
+ }
+ }
+
+ private void configureAndAddSearchHeader(LayoutInflater inflater) {
+ View headerSearch = inflater.inflate(R.layout.theme_grid_cardview_header_search, null);
+ headerSearch.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mCallback.onSearchClicked();
+ }
+ });
+ configureFilterSpinner(headerSearch);
+ ImageButton searchButton = (ImageButton) headerSearch.findViewById(R.id.theme_search);
+ searchButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mCallback.onSearchClicked();
+ }
+ });
+ }
+
+ private void configureFilterSpinner(View headerSearch) {
+ mSpinner = (Spinner) headerSearch.findViewById(R.id.theme_filter_spinner);
+ ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(mThemeBrowserActivity, R.array.themes_filter_array, android.R.layout.simple_spinner_item);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mSpinner.setAdapter(adapter);
+ mGridView.addHeaderView(headerSearch);
+ mSpinner.setOnItemSelectedListener(this);
+ }
+
+ private void restoreState(Bundle savedInstanceState) {
+ if (savedInstanceState != null) {
+ mPage = savedInstanceState.getInt(BUNDLE_PAGE, 1);
+ }
+ }
+
+ private void setEmptyViewVisible(boolean visible) {
+ if (getView() == null || !isAdded()) {
+ return;
+ }
+ mEmptyView.setVisibility(visible ? RelativeLayout.VISIBLE : RelativeLayout.GONE);
+ mGridView.setVisibility(visible ? View.GONE : View.VISIBLE);
+ if (visible && !NetworkUtils.isNetworkAvailable(mThemeBrowserActivity)) {
+ mEmptyTextView.setText(R.string.no_network_title);
+ }
+ }
+
+ /**
+ * Fetch themes for a given ThemeFilterType.
+ *
+ * @return a db Cursor or null if current blog is null
+ */
+ protected Cursor fetchThemes(int position) {
+ if (WordPress.getCurrentBlog() == null) {
+ return null;
+ }
+
+ String blogId = String.valueOf(WordPress.getCurrentBlog().getRemoteBlogId());
+ switch (position) {
+ case THEME_FILTER_PREMIUM_INDEX:
+ return WordPress.wpDB.getThemesPremium(blogId);
+ case THEME_FILTER_ALL_INDEX:
+ return WordPress.wpDB.getThemesAll(blogId);
+ case THEME_FILTER_FREE_INDEX:
+ default:
+ return WordPress.wpDB.getThemesFree(blogId);
+ }
+ }
+
+ protected void refreshView(int position) {
+ Cursor cursor = fetchThemes(position);
+ if (cursor == null) {
+ return;
+ }
+ if (mAdapter == null) {
+ mAdapter = new ThemeBrowserAdapter(mThemeBrowserActivity, cursor, false, mCallback);
+ }
+ if (mNoResultText.isShown()) {
+ mNoResultText.setVisibility(View.GONE);
+ }
+ mAdapter.changeCursor(cursor);
+ mAdapter.notifyDataSetChanged();
+ setEmptyViewVisible(mAdapter.getCount() == 0);
+ mProgressBar.setVisibility(View.GONE);
+ }
+
+ private boolean shouldFetchThemesOnScroll(int lastVisibleCount, int totalItemCount) {
+ if (totalItemCount < ThemeBrowserActivity.THEME_FETCH_MAX) {
+ return false;
+ } else {
+ int numberOfColumns = mGridView.getNumColumns();
+ return lastVisibleCount >= totalItemCount - numberOfColumns;
+ }
+ }
+
+ protected int getSpinnerPosition() {
+ if (mSpinner != null) {
+ return mSpinner.getSelectedItemPosition();
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public void onMovedToScrapHeap(View view) {
+ // cancel image fetch requests if the view has been moved to recycler.
+ NetworkImageView niv = (NetworkImageView) view.findViewById(R.id.theme_grid_item_image);
+ if (niv != null) {
+ // this tag is set in the ThemeBrowserAdapter class
+ String requestUrl = (String) niv.getTag();
+ if (requestUrl != null) {
+ // need a listener to cancel request, even if the listener does nothing
+ ImageContainer container = WordPress.imageLoader.get(requestUrl, new ImageListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ }
+
+ @Override
+ public void onResponse(ImageContainer response, boolean isImmediate) {
+ }
+
+ });
+ container.cancelRequest();
+ }
+ }
+ }
+
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ if (mSpinner != null) {
+ refreshView(position);
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+
+ }
+
+ @Override
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+
+ }
+
+ @Override
+ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+ if (shouldFetchThemesOnScroll(firstVisibleItem + visibleItemCount, totalItemCount) && NetworkUtils.isNetworkAvailable(getActivity())) {
+ mPage++;
+ mThemeBrowserActivity.fetchThemes();
+ mProgressBar.setVisibility(View.VISIBLE);
+ }
+ }
+}