Java tutorial
/* * Copyright 2016 Hippo Seven * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hippo.ehviewer.ui.scene; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.DialogInterface; import android.content.res.Resources; import android.graphics.Point; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.design.widget.FloatingActionButton; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.TextUtils; import android.text.style.ImageSpan; import android.util.SparseBooleanArray; import android.view.Display; import android.view.Gravity; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView; import com.github.amlcurran.showcaseview.ShowcaseView; import com.github.amlcurran.showcaseview.SimpleShowcaseEventListener; import com.github.amlcurran.showcaseview.targets.PointTarget; import com.hippo.annotation.Implemented; import com.hippo.drawable.DrawerArrowDrawable; import com.hippo.easyrecyclerview.EasyRecyclerView; import com.hippo.easyrecyclerview.FastScroller; import com.hippo.easyrecyclerview.LinearDividerItemDecoration; import com.hippo.ehviewer.EhApplication; import com.hippo.ehviewer.EhDB; import com.hippo.ehviewer.R; import com.hippo.ehviewer.Settings; import com.hippo.ehviewer.client.EhClient; import com.hippo.ehviewer.client.EhRequest; import com.hippo.ehviewer.client.EhUrl; import com.hippo.ehviewer.client.data.FavListUrlBuilder; import com.hippo.ehviewer.client.data.GalleryInfo; import com.hippo.ehviewer.client.parser.FavoritesParser; import com.hippo.ehviewer.ui.MainActivity; import com.hippo.ehviewer.ui.annotation.DrawerLifeCircle; import com.hippo.ehviewer.ui.annotation.ViewLifeCircle; import com.hippo.ehviewer.ui.annotation.WholeLifeCircle; import com.hippo.ehviewer.widget.SearchBar; import com.hippo.refreshlayout.RefreshLayout; import com.hippo.ripple.Ripple; import com.hippo.scene.Announcer; import com.hippo.scene.SceneFragment; import com.hippo.util.ApiHelper; import com.hippo.util.DrawableManager; import com.hippo.widget.ContentLayout; import com.hippo.widget.FabLayout; import com.hippo.widget.SearchBarMover; import com.hippo.yorozuya.LayoutUtils; import com.hippo.yorozuya.ObjectUtils; import com.hippo.yorozuya.ResourcesUtils; import com.hippo.yorozuya.SimpleHandler; import com.hippo.yorozuya.ViewUtils; import junit.framework.Assert; import java.util.ArrayList; import java.util.Collections; import java.util.List; // TODO Get favorite, modify favorite, add favorite, what a mess! public class FavoritesScene extends BaseScene implements EasyRecyclerView.OnItemClickListener, EasyRecyclerView.OnItemLongClickListener, FastScroller.OnDragHandlerListener, SearchBarMover.Helper, SearchBar.Helper, FabLayout.OnClickFabListener, EasyRecyclerView.CustomChoiceListener, AdapterView.OnItemClickListener { private static final long ANIMATE_TIME = 300L; private static final String KEY_URL_BUILDER = "url_builder"; private static final String KEY_SEARCH_MODE = "search_mode"; private static final String KEY_HAS_FIRST_REFRESH = "has_first_refresh"; private static final String KEY_FAV_COUNT_ARRAY = "fav_count_array"; @Nullable @ViewLifeCircle private EasyRecyclerView mRecyclerView; @Nullable @ViewLifeCircle private SearchBar mSearchBar; @Nullable @ViewLifeCircle private FabLayout mFabLayout; @Nullable @ViewLifeCircle private FavoritesAdapter mAdapter; @Nullable @ViewLifeCircle private FavoritesHelper mHelper; @Nullable @ViewLifeCircle private SearchBarMover mSearchBarMover; @Nullable @ViewLifeCircle private DrawerArrowDrawable mLeftDrawable; @Nullable @DrawerLifeCircle private ArrayAdapter<String> mDrawerAdapter; @Nullable @DrawerLifeCircle private List<String> mDrawerList; @Nullable @WholeLifeCircle private EhClient mClient; @Nullable @WholeLifeCircle private String[] mFavCatArray; @Nullable @WholeLifeCircle private FavListUrlBuilder mUrlBuilder; public int current; // -1 for error public int limit; // -1 for error @Nullable private int[] mFavCountArray; private boolean mHasFirstRefresh; private boolean mSearchMode; // Avoid unnecessary search bar update private String mOldFavCat; // Avoid unnecessary search bar update private String mOldKeyword; // For modify action private boolean mEnableModify; // For modify action private int mModifyFavCat; // For modify action private final List<GalleryInfo> mModifyGiList = new ArrayList<>(); // For modify action private boolean mModifyAdd; private ShowcaseView mShowcaseView; @Override public int getNavCheckedItem() { return R.id.nav_favourite; } @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Context context = getContext2(); Assert.assertNotNull(context); mClient = EhApplication.getEhClient(context); mFavCatArray = Settings.getFavCat(); if (savedInstanceState == null) { onInit(); } else { onRestore(savedInstanceState); } } private void onInit() { mUrlBuilder = new FavListUrlBuilder(); mUrlBuilder.setFavCat(Settings.getRecentFavCat()); mSearchMode = false; } private void onRestore(Bundle savedInstanceState) { mUrlBuilder = savedInstanceState.getParcelable(KEY_URL_BUILDER); if (mUrlBuilder == null) { mUrlBuilder = new FavListUrlBuilder(); } mSearchMode = savedInstanceState.getBoolean(KEY_SEARCH_MODE); mHasFirstRefresh = savedInstanceState.getBoolean(KEY_HAS_FIRST_REFRESH); mFavCountArray = savedInstanceState.getIntArray(KEY_FAV_COUNT_ARRAY); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); boolean hasFirstRefresh; if (mHelper != null && 1 == mHelper.getShownViewIndex()) { hasFirstRefresh = false; } else { hasFirstRefresh = mHasFirstRefresh; } outState.putBoolean(KEY_HAS_FIRST_REFRESH, hasFirstRefresh); outState.putParcelable(KEY_URL_BUILDER, mUrlBuilder); outState.putBoolean(KEY_SEARCH_MODE, mSearchMode); outState.putIntArray(KEY_FAV_COUNT_ARRAY, mFavCountArray); } @Override public void onDestroy() { super.onDestroy(); mClient = null; mFavCatArray = null; mUrlBuilder = null; } @Nullable @Override public View onCreateView2(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.scene_favorites, container, false); ContentLayout contentLayout = (ContentLayout) view.findViewById(R.id.content_layout); mRecyclerView = contentLayout.getRecyclerView(); FastScroller fastScroller = contentLayout.getFastScroller(); RefreshLayout refreshLayout = contentLayout.getRefreshLayout(); mSearchBar = (SearchBar) ViewUtils.$$(view, R.id.search_bar); mFabLayout = (FabLayout) ViewUtils.$$(view, R.id.fab_layout); Context context = getContext2(); Assert.assertNotNull(context); Resources resources = context.getResources(); int paddingTopSB = resources.getDimensionPixelOffset(R.dimen.gallery_padding_top_search_bar); mHelper = new FavoritesHelper(); mHelper.setEmptyString(resources.getString(R.string.gallery_list_empty_hit)); contentLayout.setHelper(mHelper); contentLayout.getFastScroller().setOnDragHandlerListener(this); mAdapter = new FavoritesAdapter(inflater, resources, mRecyclerView, Settings.getListMode()); mRecyclerView.setSelector(Ripple.generateRippleDrawable(context, false)); mRecyclerView.setDrawSelectorOnTop(true); mRecyclerView.hasFixedSize(); mRecyclerView.setClipToPadding(false); mRecyclerView.setOnItemClickListener(this); mRecyclerView.setOnItemLongClickListener(this); mRecyclerView.setChoiceMode(EasyRecyclerView.CHOICE_MODE_MULTIPLE_CUSTOM); mRecyclerView.setCustomCheckedListener(this); fastScroller.setPadding(fastScroller.getPaddingLeft(), fastScroller.getPaddingTop() + paddingTopSB, fastScroller.getPaddingRight(), fastScroller.getPaddingBottom()); refreshLayout.setHeaderTranslationY(paddingTopSB); mLeftDrawable = new DrawerArrowDrawable(context); mSearchBar.setLeftDrawable(mLeftDrawable); mSearchBar.setRightDrawable(DrawableManager.getDrawable(context, R.drawable.v_magnify_x24)); mSearchBar.setHelper(this); mSearchBar.setAllowEmptySearch(false); updateSearchBar(); mSearchBarMover = new SearchBarMover(this, mSearchBar, mRecyclerView); mFabLayout.setExpanded(false, false); mFabLayout.setAutoCancel(false); mFabLayout.setHidePrimaryFab(true); mFabLayout.setOnClickFabListener(this); addAboveSnackView(mFabLayout); // Restore search mode if (mSearchMode) { mSearchMode = false; enterSearchMode(false); } // Only refresh for the first time if (!mHasFirstRefresh) { mHasFirstRefresh = true; mHelper.firstRefresh(); } guideCollections(); return view; } private void guideCollections() { Activity activity = getActivity2(); if (null == activity || !Settings.getGuideCollections()) { return; } Display display = activity.getWindowManager().getDefaultDisplay(); Point point = new Point(); display.getSize(point); mShowcaseView = new ShowcaseView.Builder(activity).withMaterialShowcase().setStyle(R.style.Guide) .setTarget(new PointTarget(point.x, point.y / 3)).blockAllTouches() .setContentTitle(R.string.guide_collections_title).setContentText(R.string.guide_collections_text) .replaceEndButton(R.layout.button_guide) .setShowcaseEventListener(new SimpleShowcaseEventListener() { @Override public void onShowcaseViewDidHide(ShowcaseView showcaseView) { mShowcaseView = null; ViewUtils.removeFromParent(showcaseView); Settings.putGuideCollections(false); openDrawer(Gravity.RIGHT); } }).build(); } // keyword of mUrlBuilder, fav cat of mUrlBuilder, mFavCatArray. // They changed, call it private void updateSearchBar() { Context context = getContext2(); if (null == context || null == mUrlBuilder || null == mSearchBar || null == mFavCatArray) { return; } // Update title int favCat = mUrlBuilder.getFavCat(); String favCatName; if (favCat >= 0 && favCat < 10) { favCatName = mFavCatArray[favCat]; } else if (favCat == FavListUrlBuilder.FAV_CAT_LOCAL) { favCatName = getString(R.string.local_favorites); } else { favCatName = getString(R.string.cloud_favorites); } String keyword = mUrlBuilder.getKeyword(); if (TextUtils.isEmpty(keyword)) { if (!ObjectUtils.equal(favCatName, mOldFavCat)) { mSearchBar.setTitle(getString(R.string.favorites_title, favCatName)); } } else { if (!ObjectUtils.equal(favCatName, mOldFavCat) || !ObjectUtils.equal(keyword, mOldKeyword)) { mSearchBar.setTitle(getString(R.string.favorites_title_2, favCatName, keyword)); } } // Update hint if (!ObjectUtils.equal(favCatName, mOldFavCat)) { Drawable searchImage = DrawableManager.getDrawable(context, R.drawable.v_magnify_x24); SpannableStringBuilder ssb = new SpannableStringBuilder(" "); ssb.append(getString(R.string.favorites_search_bar_hint, favCatName)); int textSize = (int) (mSearchBar.getEditTextTextSize() * 1.25); if (searchImage != null) { searchImage.setBounds(0, 0, textSize, textSize); ssb.setSpan(new ImageSpan(searchImage), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } mSearchBar.setEditTextHint(ssb); } mOldFavCat = favCatName; mOldKeyword = keyword; // Save recent fav cat Settings.putRecentFavCat(mUrlBuilder.getFavCat()); } @Override public void onDestroyView() { super.onDestroyView(); if (null != mShowcaseView) { ViewUtils.removeFromParent(mShowcaseView); mShowcaseView = null; } if (null != mHelper) { if (1 == mHelper.getShownViewIndex()) { mHasFirstRefresh = false; } mHelper = null; } if (null != mRecyclerView) { mRecyclerView.stopScroll(); mRecyclerView = null; } if (null != mFabLayout) { removeAboveSnackView(mFabLayout); mFabLayout = null; } mAdapter = null; mSearchBar = null; mSearchBarMover = null; mLeftDrawable = null; mOldFavCat = null; mOldKeyword = null; } private class InfoHolder extends RecyclerView.ViewHolder { private final TextView key; private final TextView value; public InfoHolder(View itemView) { super(itemView); key = (TextView) ViewUtils.$$(itemView, R.id.key); value = (TextView) ViewUtils.$$(itemView, R.id.value); } } private class InfoAdapter extends RecyclerView.Adapter<InfoHolder> { private static final int TYPE_HEADER = 0; private static final int TYPE_DATA = 1; private final LayoutInflater mInflater; public InfoAdapter(LayoutInflater inflater) { mInflater = inflater; } @Override public int getItemViewType(int position) { return 0 == position ? TYPE_HEADER : TYPE_DATA; } @Override public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new InfoHolder(mInflater.inflate( TYPE_HEADER == viewType ? R.layout.item_favorite_info_header : R.layout.item_favorite_info_data, parent, false)); } @Override @SuppressLint("SetTextI18n") public void onBindViewHolder(InfoHolder holder, int position) { if (0 == position) { holder.key.setText(R.string.collections); holder.value.setText(R.string.count); holder.itemView.setEnabled(false); } else { if (null == mFavCatArray || null == mFavCountArray || mFavCatArray.length < position || mFavCountArray.length < position) { return; } holder.key.setText(mFavCatArray[position - 1]); holder.value.setText(Integer.toString(mFavCountArray[position - 1])); holder.itemView.setEnabled(true); } } @Override public int getItemCount() { return 11; } } @SuppressLint("InflateParams") private void showFavoritesInfoDialog() { Context context = getContext2(); if (null == context || null == mFavCatArray || null == mFavCountArray) { return; } AlertDialog.Builder builder = new AlertDialog.Builder(context); context = builder.getContext(); final LayoutInflater inflater = LayoutInflater.from(context); EasyRecyclerView rv = (EasyRecyclerView) inflater.inflate(R.layout.dialog_recycler_view, null); rv.setAdapter(new InfoAdapter(inflater)); rv.setLayoutManager(new LinearLayoutManager(context)); LinearDividerItemDecoration decoration = new LinearDividerItemDecoration( LinearDividerItemDecoration.VERTICAL, context.getResources().getColor(R.color.divider), LayoutUtils.dp2pix(context, 1)); decoration.setPadding(ResourcesUtils.getAttrDimensionPixelOffset(context, R.attr.dialogPreferredPadding)); rv.addItemDecoration(decoration); rv.setSelector(Ripple.generateRippleDrawable(context, false)); rv.setClipToPadding(false); builder.setView(rv).show(); } @Override public View onCreateDrawerView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.drawer_list, container, false); Toolbar toolbar = (Toolbar) ViewUtils.$$(view, R.id.toolbar); ListView listView = (ListView) view.findViewById(R.id.list_view); final Context context = getContext2(); Assert.assertNotNull(context); toolbar.setTitle(R.string.collections); toolbar.inflateMenu(R.menu.drawer_favorites); toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { int id = item.getItemId(); switch (id) { case R.id.action_info: showFavoritesInfoDialog(); return true; case R.id.action_default_favorites_slot: String[] items = new String[12]; items[0] = getString(R.string.let_me_select); items[1] = getString(R.string.local_favorites); String[] favCat = Settings.getFavCat(); System.arraycopy(favCat, 0, items, 2, 10); new AlertDialog.Builder(context).setTitle(R.string.default_favorites_collection) .setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Settings.putDefaultFavSlot(which - 2); } }).show(); return true; } return false; } }); mDrawerList = new ArrayList<>(12); mDrawerList.add(getString(R.string.local_favorites)); mDrawerList.add(getString(R.string.cloud_favorites)); if (mFavCatArray != null) { Collections.addAll(mDrawerList, mFavCatArray); } mDrawerAdapter = new ArrayAdapter<>(context, R.layout.item_simple_list, mDrawerList); listView.setAdapter(mDrawerAdapter); listView.setOnItemClickListener(this); return view; } @Override public void onDestroyDrawerView() { super.onDestroyDrawerView(); mDrawerAdapter = null; mDrawerList = null; } @Override public void onBackPressed() { if (null != mShowcaseView) { return; } if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) { mRecyclerView.outOfCustomChoiceMode(); } else if (mSearchMode) { exitSearchMode(true); } else { finish(); } } @Override @Implemented(FastScroller.OnDragHandlerListener.class) public void onStartDragHandler() { // Lock right drawer setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.RIGHT); } @Override @Implemented(FastScroller.OnDragHandlerListener.class) public void onEndDragHandler() { // Restore right drawer if (null != mRecyclerView && !mRecyclerView.isInCustomChoice()) { setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.RIGHT); } if (mSearchBarMover != null) { mSearchBarMover.returnSearchBarPosition(); } } @Override @Implemented(EasyRecyclerView.OnItemClickListener.class) public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) { if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) { mRecyclerView.toggleItemChecked(position); } else if (mHelper != null) { GalleryInfo gi = mHelper.getDataAt(position); Bundle args = new Bundle(); args.putString(GalleryDetailScene.KEY_ACTION, GalleryDetailScene.ACTION_GALLERY_INFO); args.putParcelable(GalleryDetailScene.KEY_GALLERY_INFO, gi); Announcer announcer = new Announcer(GalleryDetailScene.class).setArgs(args); View thumb; if (ApiHelper.SUPPORT_TRANSITION && null != (thumb = view.findViewById(R.id.thumb))) { announcer.setTranHelper(new EnterGalleryDetailTransaction(thumb)); } startScene(announcer); } return true; } @Override @Implemented(EasyRecyclerView.OnItemLongClickListener.class) public boolean onItemLongClick(EasyRecyclerView parent, View view, int position, long id) { // Can not into if (mRecyclerView != null && !mSearchMode) { if (!mRecyclerView.isInCustomChoice()) { mRecyclerView.intoCustomChoiceMode(); } mRecyclerView.toggleItemChecked(position); } return true; } @Override @Implemented(SearchBarMover.Helper.class) public boolean isValidView(RecyclerView recyclerView) { return recyclerView == mRecyclerView; } @Override @Implemented(SearchBarMover.Helper.class) public RecyclerView getValidRecyclerView() { return mRecyclerView; } @Override @Implemented(SearchBarMover.Helper.class) public boolean forceShowSearchBar() { return false; } @Override @Implemented(SearchBar.Helper.class) public void onClickTitle() { // Skip if in search mode if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) { return; } if (!mSearchMode) { enterSearchMode(true); } } @Override @Implemented(SearchBar.Helper.class) public void onClickLeftIcon() { // Skip if in search mode if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) { return; } if (mSearchMode) { exitSearchMode(true); } else { toggleDrawer(Gravity.LEFT); } } @Override @Implemented(SearchBar.Helper.class) public void onClickRightIcon() { // Skip if in search mode if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) { return; } if (!mSearchMode) { enterSearchMode(true); } else { if (mSearchBar != null) { mSearchBar.applySearch(); } } } @Override @Implemented(SearchBar.Helper.class) public void onSearchEditTextClick() { } @Override @Implemented(SearchBar.Helper.class) public void onApplySearch(String query) { // Skip if in search mode if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) { return; } if (mUrlBuilder == null || mHelper == null) { return; } // Ensure outOfCustomChoiceMode to avoid error if (mRecyclerView != null) { mRecyclerView.isInCustomChoice(); } exitSearchMode(true); mUrlBuilder.setKeyword(query); updateSearchBar(); mHelper.refresh(); } @Override @Implemented(SearchBar.Helper.class) public void onSearchEditTextBackPressed() { onBackPressed(); } @Override @Implemented(FabLayout.OnClickFabListener.class) public void onClickPrimaryFab(FabLayout view, FloatingActionButton fab) { if (mRecyclerView != null) { mRecyclerView.outOfCustomChoiceMode(); } } @Override @Implemented(FabLayout.OnClickFabListener.class) public void onClickSecondaryFab(FabLayout view, FloatingActionButton fab, int position) { Context context = getContext2(); if (null == context || null == mRecyclerView || null == mHelper || !mRecyclerView.isInCustomChoice()) { return; } mModifyGiList.clear(); SparseBooleanArray stateArray = mRecyclerView.getCheckedItemPositions(); for (int i = 0, n = stateArray.size(); i < n; i++) { if (stateArray.valueAt(i)) { mModifyGiList.add(mHelper.getDataAt(stateArray.keyAt(i))); } } switch (position) { case 0: { // Delete DeleteDialogHelper helper = new DeleteDialogHelper(); new AlertDialog.Builder(context).setTitle(R.string.delete_favorites_dialog_title) .setMessage(getString(R.string.delete_favorites_dialog_message, mModifyGiList.size())) .setPositiveButton(android.R.string.ok, helper).setOnCancelListener(helper).show(); break; } case 1: { // Move MoveDialogHelper helper = new MoveDialogHelper(); // First is local favorite, the other 10 is cloud favorite String[] array = new String[11]; array[0] = getString(R.string.local_favorites); System.arraycopy(Settings.getFavCat(), 0, array, 1, 10); new AlertDialog.Builder(context).setTitle(R.string.move_favorites_dialog_title).setItems(array, helper) .setOnCancelListener(helper).show(); break; } } } @Override @Implemented(EasyRecyclerView.CustomChoiceListener.class) public void onIntoCustomChoice(EasyRecyclerView view) { if (mFabLayout != null) { mFabLayout.setExpanded(true); } if (mHelper != null) { mHelper.setRefreshLayoutEnable(false); } // Lock drawer setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.LEFT); setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.RIGHT); } @Override @Implemented(EasyRecyclerView.CustomChoiceListener.class) public void onOutOfCustomChoice(EasyRecyclerView view) { if (mFabLayout != null) { mFabLayout.setExpanded(false); } if (mHelper != null) { mHelper.setRefreshLayoutEnable(true); } // Unlock drawer setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.LEFT); setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.RIGHT); } @Override @Implemented(EasyRecyclerView.CustomChoiceListener.class) public void onItemCheckedStateChanged(EasyRecyclerView view, int position, long id, boolean checked) { if (view.getCheckedItemCount() == 0) { view.outOfCustomChoiceMode(); } } @Override @Implemented(AdapterView.OnItemClickListener.class) public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // Skip if in search mode if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) { return; } if (mUrlBuilder == null || mHelper == null) { return; } // Local favorite position is 0, All favorite position is 1, so position - 2 is OK int newFavCat = position - 2; // Check is the same if (mUrlBuilder.getFavCat() == newFavCat) { return; } // Ensure outOfCustomChoiceMode to avoid error if (mRecyclerView != null) { mRecyclerView.isInCustomChoice(); } exitSearchMode(true); mUrlBuilder.setKeyword(null); mUrlBuilder.setFavCat(newFavCat); updateSearchBar(); mHelper.refresh(); closeDrawer(Gravity.RIGHT); } private void enterSearchMode(boolean animation) { if (mSearchMode || mSearchBar == null || mSearchBarMover == null || mLeftDrawable == null) { return; } mSearchMode = true; mSearchBar.setState(SearchBar.STATE_SEARCH_LIST, animation); mSearchBarMover.returnSearchBarPosition(animation); mLeftDrawable.setArrow(ANIMATE_TIME); } private void exitSearchMode(boolean animation) { if (!mSearchMode || mSearchBar == null || mSearchBarMover == null || mLeftDrawable == null) { return; } mSearchMode = false; mSearchBar.setState(SearchBar.STATE_NORMAL, animation); mSearchBarMover.returnSearchBarPosition(); mLeftDrawable.setMenu(ANIMATE_TIME); } private void onGetFavoritesSuccess(FavoritesParser.Result result, int taskId) { if (mHelper != null && mSearchBarMover != null && mHelper.isCurrentTask(taskId)) { if (mFavCatArray != null && mDrawerList != null) { for (int i = 0; i < 10; i++) { mFavCatArray[i] = result.catArray[i]; mDrawerList.set(i + 2, result.catArray[i]); } if (mDrawerAdapter != null) { mDrawerAdapter.notifyDataSetChanged(); } } mFavCountArray = result.countArray; updateSearchBar(); mHelper.setPages(taskId, result.pages); mHelper.onGetPageData(taskId, result.galleryInfoList); } } private void onGetFavoritesFailure(Exception e, int taskId) { if (mHelper != null && mSearchBarMover != null && mHelper.isCurrentTask(taskId)) { mHelper.onGetException(taskId, e); } } @SuppressWarnings("unchecked") private void onGetFavoritesLocal(String keyword, int taskId) { if (mHelper != null && mHelper.isCurrentTask(taskId)) { List<GalleryInfo> list; if (TextUtils.isEmpty(keyword)) { list = EhDB.getAllLocalFavorites(); } else { list = EhDB.searchLocalFavorites(keyword); } if (list.size() == 0) { mHelper.setPages(taskId, 0); mHelper.onGetPageData(taskId, Collections.EMPTY_LIST); } else { mHelper.setPages(taskId, 1); mHelper.onGetPageData(taskId, list); } } } private class DeleteDialogHelper implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener { @Override public void onClick(DialogInterface dialog, int which) { if (which != DialogInterface.BUTTON_POSITIVE) { return; } if (mRecyclerView == null || mHelper == null || mUrlBuilder == null) { return; } mRecyclerView.outOfCustomChoiceMode(); if (mUrlBuilder.getFavCat() == FavListUrlBuilder.FAV_CAT_LOCAL) { // Delete local fav long[] gidArray = new long[mModifyGiList.size()]; for (int i = 0, n = mModifyGiList.size(); i < n; i++) { gidArray[i] = mModifyGiList.get(i).gid; } EhDB.removeLocalFavorites(gidArray); mModifyGiList.clear(); mHelper.refresh(); } else { // Delete cloud fav mEnableModify = true; mModifyFavCat = -1; mModifyAdd = false; mHelper.refresh(); } } @Override public void onCancel(DialogInterface dialog) { mModifyGiList.clear(); } } private class MoveDialogHelper implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener { @Override public void onClick(DialogInterface dialog, int which) { if (mRecyclerView == null || mHelper == null || mUrlBuilder == null) { return; } int srcCat = mUrlBuilder.getFavCat(); int dstCat; if (which == 0) { dstCat = FavListUrlBuilder.FAV_CAT_LOCAL; } else { dstCat = which - 1; } if (srcCat == dstCat) { return; } mRecyclerView.outOfCustomChoiceMode(); if (srcCat == FavListUrlBuilder.FAV_CAT_LOCAL) { // Move from local to cloud long[] gidArray = new long[mModifyGiList.size()]; for (int i = 0, n = mModifyGiList.size(); i < n; i++) { gidArray[i] = mModifyGiList.get(i).gid; } EhDB.removeLocalFavorites(gidArray); mEnableModify = true; mModifyFavCat = dstCat; mModifyAdd = true; mHelper.refresh(); } else if (dstCat == FavListUrlBuilder.FAV_CAT_LOCAL) { // Move from cloud to local EhDB.putLocalFavorites(mModifyGiList); mEnableModify = true; mModifyFavCat = -1; mModifyAdd = false; mHelper.refresh(); } else { mEnableModify = true; mModifyFavCat = dstCat; mModifyAdd = false; mHelper.refresh(); } } @Override public void onCancel(DialogInterface dialog) { mModifyGiList.clear(); } } private class FavoritesAdapter extends GalleryAdapter { public FavoritesAdapter(@NonNull LayoutInflater inflater, @NonNull Resources resources, @NonNull RecyclerView recyclerView, int type) { super(inflater, resources, recyclerView, type); } @Override public int getItemCount() { return null != mHelper ? mHelper.size() : 0; } @Nullable @Override public GalleryInfo getDataAt(int position) { return null != mHelper ? mHelper.getDataAt(position) : null; } } private class FavoritesHelper extends ContentLayout.ContentHelper<GalleryInfo> { @Override protected void getPageData(final int taskId, int type, int page) { MainActivity activity = getActivity2(); if (null == activity || null == mUrlBuilder || null == mClient) { return; } if (mEnableModify) { mEnableModify = false; boolean local = mUrlBuilder.getFavCat() == FavListUrlBuilder.FAV_CAT_LOCAL; if (mModifyAdd) { long[] gidArray = new long[mModifyGiList.size()]; String[] tokenArray = new String[mModifyGiList.size()]; for (int i = 0, n = mModifyGiList.size(); i < n; i++) { GalleryInfo gi = mModifyGiList.get(i); gidArray[i] = gi.gid; tokenArray[i] = gi.token; } mModifyGiList.clear(); EhRequest request = new EhRequest(); request.setMethod(EhClient.METHOD_ADD_FAVORITES_RANGE); request.setCallback(new AddFavoritesListener(getContext(), activity.getStageId(), getTag(), taskId, mUrlBuilder.getKeyword())); request.setArgs(gidArray, tokenArray, mModifyFavCat); mClient.execute(request); } else { long[] gidArray = new long[mModifyGiList.size()]; for (int i = 0, n = mModifyGiList.size(); i < n; i++) { gidArray[i] = mModifyGiList.get(i).gid; } mModifyGiList.clear(); String url; if (local) { // Local fav is shown now, but operation need be done for cloud fav url = EhUrl.getFavoritesUrl(); } else { url = mUrlBuilder.build(); } mUrlBuilder.setIndex(page); EhRequest request = new EhRequest(); request.setMethod(EhClient.METHOD_MODIFY_FAVORITES); request.setCallback(new GetFavoritesListener(getContext(), activity.getStageId(), getTag(), taskId, local, mUrlBuilder.getKeyword())); request.setArgs(url, gidArray, mModifyFavCat, Settings.getShowJpnTitle()); mClient.execute(request); } } else if (mUrlBuilder.getFavCat() == FavListUrlBuilder.FAV_CAT_LOCAL) { final String keyword = mUrlBuilder.getKeyword(); SimpleHandler.getInstance().post(new Runnable() { @Override public void run() { onGetFavoritesLocal(keyword, taskId); } }); } else { mUrlBuilder.setIndex(page); String url = mUrlBuilder.build(); EhRequest request = new EhRequest(); request.setMethod(EhClient.METHOD_GET_FAVORITES); request.setCallback(new GetFavoritesListener(getContext(), activity.getStageId(), getTag(), taskId, false, mUrlBuilder.getKeyword())); request.setArgs(url, Settings.getShowJpnTitle()); mClient.execute(request); } } @Override protected Context getContext() { return FavoritesScene.this.getContext2(); } @Override protected void notifyDataSetChanged() { // Ensure outOfCustomChoiceMode to avoid error if (mRecyclerView != null) { mRecyclerView.outOfCustomChoiceMode(); } if (mAdapter != null) { mAdapter.notifyDataSetChanged(); } } @Override protected void notifyItemRangeRemoved(int positionStart, int itemCount) { if (mAdapter != null) { mAdapter.notifyItemRangeRemoved(positionStart, itemCount); } } @Override protected void notifyItemRangeInserted(int positionStart, int itemCount) { if (mAdapter != null) { mAdapter.notifyItemRangeInserted(positionStart, itemCount); } } @Override public void onShowView(View hiddenView, View shownView) { if (null != mSearchBarMover) { mSearchBarMover.showSearchBar(); } } @Override protected void onScrollToPosition(int postion) { if (0 == postion) { if (null != mSearchBarMover) { mSearchBarMover.showSearchBar(); } } } } private static class AddFavoritesListener extends EhCallback<FavoritesScene, Void> { private final int mTaskId; private final String mKeyword; public AddFavoritesListener(Context context, int stageId, String sceneTag, int taskId, String keyword) { super(context, stageId, sceneTag); mTaskId = taskId; mKeyword = keyword; } @Override public void onSuccess(Void result) { FavoritesScene scene = getScene(); if (scene != null) { scene.onGetFavoritesLocal(mKeyword, mTaskId); } } @Override public void onFailure(Exception e) { FavoritesScene scene = getScene(); if (scene != null) { scene.onGetFavoritesLocal(mKeyword, mTaskId); } } @Override public void onCancel() { } @Override public boolean isInstance(SceneFragment scene) { return scene instanceof FavoritesScene; } } private static class GetFavoritesListener extends EhCallback<FavoritesScene, FavoritesParser.Result> { private final int mTaskId; // Local fav is shown now, but operation need be done for cloud fav private final boolean mLocal; private final String mKeyword; public GetFavoritesListener(Context context, int stageId, String sceneTag, int taskId, boolean local, String keyword) { super(context, stageId, sceneTag); mTaskId = taskId; mLocal = local; mKeyword = keyword; } @Override public void onSuccess(FavoritesParser.Result result) { // Put fav cat Settings.putFavCat(result.catArray); FavoritesScene scene = getScene(); if (scene != null) { if (mLocal) { scene.onGetFavoritesLocal(mKeyword, mTaskId); } else { scene.onGetFavoritesSuccess(result, mTaskId); } } } @Override public void onFailure(Exception e) { FavoritesScene scene = getScene(); if (scene != null) { if (mLocal) { e.printStackTrace(); scene.onGetFavoritesLocal(mKeyword, mTaskId); } else { scene.onGetFavoritesFailure(e, mTaskId); } } } @Override public void onCancel() { } @Override public boolean isInstance(SceneFragment scene) { return scene instanceof FavoritesScene; } } }