diff options
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.java | 383 |
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); + } + } +} |