Here are the examples of the java api com.hippo.easyrecyclerview.EasyRecyclerView taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
57 Examples
19
Source : HistoryScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
@Override
public boolean onItemLongClick(EasyRecyclerView parent, View view, int position, long id) {
final Context context = getContext2();
final MainActivity activity = getActivity2();
if (null == context || null == activity || null == mLazyList) {
return false;
}
final GalleryInfo gi = mLazyList.get(position);
new AlertDialog.Builder(context).setreplacedle(EhUtils.getSuitablereplacedle(gi)).sereplacedems(R.array.gallery_list_menu_entries, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch(which) {
case // Download
0:
CommonOperations.startDownload(activity, gi, false);
break;
case // Favorites
1:
CommonOperations.addToFavorites(activity, gi, new addToFavoriteListener(context, activity.getStageId(), getTag()));
break;
}
}
}).show();
return true;
}
19
Source : GalleryInfoScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
public final clreplaced GalleryInfoScene extends ToolbarScene implements EasyRecyclerView.OnItemClickListener {
public static final String KEY_GALLERY_DETAIL = "gallery_detail";
public static final String KEY_KEYS = "keys";
public static final String KEY_VALUES = "values";
private static final int INDEX_URL = 3;
private static final int INDEX_PARENT = 10;
/*---------------
Whole life cycle
---------------*/
@Nullable
private ArrayList<String> mKeys;
@Nullable
private ArrayList<String> mValues;
@Nullable
private EasyRecyclerView mRecyclerView;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void handlerArgs(Bundle args) {
if (args == null) {
return;
}
GalleryDetail gd = args.getParcelable(KEY_GALLERY_DETAIL);
if (gd == null) {
return;
}
if (mKeys == null || mValues == null) {
return;
}
Resources resources = getResources2();
replacedertUtils.replacedertNotNull(resources);
mKeys.add(resources.getString(R.string.header_key));
mValues.add(resources.getString(R.string.header_value));
mKeys.add(resources.getString(R.string.key_gid));
mValues.add(Long.toString(gd.gid));
mKeys.add(resources.getString(R.string.key_token));
mValues.add(gd.token);
mKeys.add(resources.getString(R.string.key_url));
mValues.add(EhUrl.getGalleryDetailUrl(gd.gid, gd.token));
mKeys.add(resources.getString(R.string.key_replacedle));
mValues.add(gd.replacedle);
mKeys.add(resources.getString(R.string.key_replacedle_jpn));
mValues.add(gd.replacedleJpn);
mKeys.add(resources.getString(R.string.key_thumb));
mValues.add(gd.thumb);
mKeys.add(resources.getString(R.string.key_category));
mValues.add(EhUtils.getCategory(gd.category));
mKeys.add(resources.getString(R.string.key_uploader));
mValues.add(gd.uploader);
mKeys.add(resources.getString(R.string.key_posted));
mValues.add(gd.posted);
mKeys.add(resources.getString(R.string.key_parent));
mValues.add(gd.parent);
mKeys.add(resources.getString(R.string.key_visible));
mValues.add(gd.visible);
mKeys.add(resources.getString(R.string.key_language));
mValues.add(gd.language);
mKeys.add(resources.getString(R.string.key_pages));
mValues.add(Integer.toString(gd.pages));
mKeys.add(resources.getString(R.string.key_size));
mValues.add(gd.size);
mKeys.add(resources.getString(R.string.key_favorite_count));
mValues.add(Integer.toString(gd.favoriteCount));
mKeys.add(resources.getString(R.string.key_favorited));
mValues.add(Boolean.toString(gd.isFavorited));
mKeys.add(resources.getString(R.string.key_rating_count));
mValues.add(Integer.toString(gd.ratingCount));
mKeys.add(resources.getString(R.string.key_rating));
mValues.add(Float.toString(gd.rating));
mKeys.add(resources.getString(R.string.key_torrents));
mValues.add(Integer.toString(gd.torrentCount));
mKeys.add(resources.getString(R.string.key_torrent_url));
mValues.add(gd.torrentUrl);
mKeys.add(resources.getString(R.string.favorite_name));
mValues.add(gd.favoriteName);
}
protected void onInit() {
mKeys = new ArrayList<>();
mValues = new ArrayList<>();
handlerArgs(getArguments());
}
protected void onRestore(@NonNull Bundle savedInstanceState) {
mKeys = savedInstanceState.getStringArrayList(KEY_KEYS);
mValues = savedInstanceState.getStringArrayList(KEY_VALUES);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList(KEY_KEYS, mKeys);
outState.putStringArrayList(KEY_VALUES, mValues);
}
@SuppressWarnings("deprecation")
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_gallery_info, container, false);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(view, R.id.recycler_view);
InfoAdapter adapter = new InfoAdapter();
mRecyclerView.setAdapter(adapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setPadding(context.getResources().getDimensionPixelOffset(R.dimen.keyline_margin));
mRecyclerView.addItemDecoration(decoration);
mRecyclerView.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
mRecyclerView.setClipToPadding(false);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setOnItemClickListener(this);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.gallery_info);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
}
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
Context context = getContext2();
if (null != context && 0 != position && null != mValues) {
if (position == INDEX_PARENT) {
UrlOpener.openUrl(context, mValues.get(position), true);
} else {
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
cmb.setPrimaryClip(ClipData.newPlainText(null, mValues.get(position)));
if (position == INDEX_URL) {
// Save it to avoid detect the gallery
Settings.putClipboardTextHashCode(mValues.get(position).hashCode());
}
showTip(R.string.copied_to_clipboard, LENGTH_SHORT);
}
return true;
} else {
return false;
}
}
@Override
public void onNavigationClick() {
onBackPressed();
}
private static clreplaced InfoHolder extends RecyclerView.ViewHolder {
private final TextView key;
private final TextView value;
public InfoHolder(View itemView) {
super(itemView);
key = (TextView) itemView.findViewById(R.id.key);
value = (TextView) itemView.findViewById(R.id.value);
}
}
private clreplaced 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() {
mInflater = getLayoutInflater2();
replacedertUtils.replacedertNotNull(mInflater);
}
@Override
public int gereplacedemViewType(int position) {
if (position == 0) {
return TYPE_HEADER;
} else {
return TYPE_DATA;
}
}
@Override
public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new InfoHolder(mInflater.inflate(viewType == TYPE_HEADER ? R.layout.item_gallery_info_header : R.layout.item_gallery_info_data, parent, false));
}
@Override
public void onBindViewHolder(InfoHolder holder, int position) {
if (mKeys != null && mValues != null) {
holder.key.setText(mKeys.get(position));
holder.value.setText(mValues.get(position));
holder.itemView.setEnabled(position != 0);
}
}
@Override
public int gereplacedemCount() {
return mKeys == null || mValues == null ? 0 : Math.min(mKeys.size(), mValues.size());
}
}
}
19
Source : GalleryInfoScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
Context context = getContext2();
if (null != context && 0 != position && null != mValues) {
if (position == INDEX_PARENT) {
UrlOpener.openUrl(context, mValues.get(position), true);
} else {
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
cmb.setPrimaryClip(ClipData.newPlainText(null, mValues.get(position)));
if (position == INDEX_URL) {
// Save it to avoid detect the gallery
Settings.putClipboardTextHashCode(mValues.get(position).hashCode());
}
showTip(R.string.copied_to_clipboard, LENGTH_SHORT);
}
return true;
} else {
return false;
}
}
19
Source : GalleryCommentsScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
MainActivity activity = getActivity2();
if (null == activity) {
return false;
}
RecyclerView.ViewHolder holder = parent.getChildViewHolder(view);
if (holder instanceof ActualCommentHolder) {
ActualCommentHolder commentHolder = (ActualCommentHolder) holder;
ClickableSpan span = commentHolder.comment.getCurrentSpan();
commentHolder.comment.clearCurrentSpan();
if (span instanceof URLSpan) {
UrlOpener.openUrl(activity, ((URLSpan) span).getURL(), true);
} else {
showCommentDialog(position);
}
} else if (holder instanceof MoreCommentHolder && !mRefreshingComments && mAdapter != null) {
mRefreshingComments = true;
mShowAllComments = true;
mAdapter.notifyItemChanged(position);
String url = getGalleryDetailUrl();
if (url != null) {
// Request
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_GET_GALLERY_DETAIL).setArgs(url).setCallback(new RefreshCommentListener(activity, activity.getStageId(), getTag()));
EhApplication.getEhClient(activity).execute(request);
}
}
return true;
}
19
Source : ExcludedLanguagesActivity.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
public clreplaced ExcludedLanguagesActivity extends ToolbarActivity implements View.OnClickListener {
private static final String KEY_SELECTIONS = "selections";
private static final int ROW_COUNT = 17;
private static final int[] LANGUAGE_STR_IDS = { R.string.language_replacedanese, R.string.language_english, R.string.language_chinese, R.string.language_dutch, R.string.language_french, R.string.language_german, R.string.language_hungarian, R.string.language_italian, R.string.language_korean, R.string.language_polish, R.string.language_portuguese, R.string.language_russian, R.string.language_spanish, R.string.language_thai, R.string.language_vietnamese, R.string.language_na, R.string.language_other };
private static final String[] LANGUAGES = { EhConfig.replacedANESE_ORIGINAL, EhConfig.replacedANESE_TRANSLATED, EhConfig.replacedANESE_REWRITE, EhConfig.ENGLISH_ORIGINAL, EhConfig.ENGLISH_TRANSLATED, EhConfig.ENGLISH_REWRITE, EhConfig.CHINESE_ORIGINAL, EhConfig.CHINESE_TRANSLATED, EhConfig.CHINESE_REWRITE, EhConfig.DUTCH_ORIGINAL, EhConfig.DUTCH_TRANSLATED, EhConfig.DUTCH_REWRITE, EhConfig.FRENCH_ORIGINAL, EhConfig.FRENCH_TRANSLATED, EhConfig.FRENCH_REWRITE, EhConfig.GERMAN_ORIGINAL, EhConfig.GERMAN_TRANSLATED, EhConfig.GERMAN_REWRITE, EhConfig.HUNGARIAN_ORIGINAL, EhConfig.HUNGARIAN_TRANSLATED, EhConfig.HUNGARIAN_REWRITE, EhConfig.ITALIAN_ORIGINAL, EhConfig.ITALIAN_TRANSLATED, EhConfig.ITALIAN_REWRITE, EhConfig.KOREAN_ORIGINAL, EhConfig.KOREAN_TRANSLATED, EhConfig.KOREAN_REWRITE, EhConfig.POLISH_ORIGINAL, EhConfig.POLISH_TRANSLATED, EhConfig.POLISH_REWRITE, EhConfig.PORTUGUESE_ORIGINAL, EhConfig.PORTUGUESE_TRANSLATED, EhConfig.PORTUGUESE_REWRITE, EhConfig.RUSSIAN_ORIGINAL, EhConfig.RUSSIAN_TRANSLATED, EhConfig.RUSSIAN_REWRITE, EhConfig.SPANISH_ORIGINAL, EhConfig.SPANISH_TRANSLATED, EhConfig.SPANISH_REWRITE, EhConfig.THAI_ORIGINAL, EhConfig.THAI_TRANSLATED, EhConfig.THAI_REWRITE, EhConfig.VIETNAMESE_ORIGINAL, EhConfig.VIETNAMESE_TRANSLATED, EhConfig.VIETNAMESE_REWRITE, EhConfig.NA_ORIGINAL, EhConfig.NA_TRANSLATED, EhConfig.NA_REWRITE, EhConfig.OTHER_ORIGINAL, EhConfig.OTHER_TRANSLATED, EhConfig.OTHER_REWRITE };
private final boolean[][] mSelections = new boolean[ROW_COUNT][3];
/*---------------
Whole life cycle
---------------*/
@Nullable
private View mCancel;
@Nullable
private View mOk;
@Nullable
private View mSelectAll;
@Nullable
private View mDeselectAll;
@Nullable
private View mInvertSelection;
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private LanguageAdapter mAdapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scene_excluded_languages);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
if (null == savedInstanceState) {
onInit();
} else {
onRestore(savedInstanceState);
}
mCancel = ViewUtils.$$(this, R.id.cancel);
mOk = ViewUtils.$$(this, R.id.ok);
mSelectAll = ViewUtils.$$(this, R.id.select_all);
mDeselectAll = ViewUtils.$$(this, R.id.deselect_all);
mInvertSelection = ViewUtils.$$(this, R.id.invert_selection);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(this, R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setClipToPadding(false);
mAdapter = new LanguageAdapter();
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mCancel.setOnClickListener(this);
mOk.setOnClickListener(this);
mSelectAll.setOnClickListener(this);
mDeselectAll.setOnClickListener(this);
mInvertSelection.setOnClickListener(this);
boolean isDarkTheme = !AttrResources.getAttrBoolean(this, R.attr.isLightTheme);
Ripple.addRipple(mCancel, isDarkTheme);
Ripple.addRipple(mOk, isDarkTheme);
Ripple.addRipple(mSelectAll, isDarkTheme);
Ripple.addRipple(mDeselectAll, isDarkTheme);
Ripple.addRipple(mInvertSelection, isDarkTheme);
}
private boolean isDecimal(String str) {
int length = str.length();
// "" is not decimal
if (length <= 0) {
return false;
}
for (int i = 0; i < length; i++) {
char ch = str.charAt(i);
if (ch < '0' || ch > '9') {
return false;
}
}
return true;
}
private void onInit() {
String excludedLanguages = Settings.getExcludedLanguages();
if (null == excludedLanguages) {
return;
}
String[] languages = excludedLanguages.split("x");
int iLength = languages.length;
int jLength = LANGUAGES.length;
for (int i = 0, j = 0; i < iLength; i++) {
String language = languages[i];
if (!isDecimal(language)) {
continue;
}
for (; j < jLength; j++) {
String pattern = LANGUAGES[j];
if (pattern.equals(language)) {
// Get it
int row = j / 3;
int column = j % 3;
mSelections[row][column] = true;
break;
}
}
}
}
private long saveSelectionsToLong() {
boolean[][] selections = mSelections;
long value = 0;
for (int i = 0; i < ROW_COUNT; i++) {
for (int j = 0; j < 3; j++) {
if (selections[i][j]) {
value |= 1 << (i * 3 + j);
}
}
}
return value;
}
private void restoreSelectionsFromLong(long value) {
boolean[][] selections = mSelections;
for (int i = 0; i < ROW_COUNT; i++) {
for (int j = 0; j < 3; j++) {
selections[i][j] = 0 != ((value >>> (i * 3 + j)) & 1);
}
}
}
private void onRestore(@NonNull Bundle savedInstanceState) {
restoreSelectionsFromLong(savedInstanceState.getLong(KEY_SELECTIONS));
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(KEY_SELECTIONS, saveSelectionsToLong());
}
@Override
protected void onDestroy() {
super.onDestroy();
mCancel = null;
mOk = null;
mSelectAll = null;
mDeselectAll = null;
mInvertSelection = null;
mRecyclerView = null;
mAdapter = null;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.gereplacedemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onClick(View v) {
if (null == mAdapter) {
return;
}
if (v == mCancel) {
finish();
} else if (v == mOk) {
StringBuilder sb = new StringBuilder();
int i = 0;
boolean first = true;
for (boolean[] selections : mSelections) {
for (boolean b : selections) {
if (b) {
if (!first) {
sb.append("x");
} else {
first = false;
}
sb.append(LANGUAGES[i]);
}
i++;
}
}
String excludedLanguages = sb.toString();
Settings.putExcludedLanguages(excludedLanguages);
finish();
} else if (v == mSelectAll) {
for (boolean[] selections : mSelections) {
int length = selections.length;
for (int i = 0; i < length; i++) {
selections[i] = true;
}
}
mAdapter.notifyDataSetChanged();
} else if (v == mDeselectAll) {
for (boolean[] selections : mSelections) {
int length = selections.length;
for (int i = 0; i < length; i++) {
selections[i] = false;
}
}
mAdapter.notifyDataSetChanged();
} else if (v == mInvertSelection) {
for (boolean[] selections : mSelections) {
int length = selections.length;
for (int i = 0; i < length; i++) {
selections[i] = !selections[i];
}
}
mAdapter.notifyDataSetChanged();
}
}
private clreplaced LanguageHolder extends RecyclerView.ViewHolder implements SensitiveCheckBox.OnCheckedChangeListener {
public TextView language;
public SensitiveCheckBox original;
public SensitiveCheckBox translated;
public SensitiveCheckBox rewrite;
public LanguageHolder(View itemView) {
super(itemView);
ViewGroup viewGroup = (ViewGroup) itemView;
language = (TextView) viewGroup.getChildAt(0);
original = (SensitiveCheckBox) viewGroup.getChildAt(1);
translated = (SensitiveCheckBox) viewGroup.getChildAt(2);
rewrite = (SensitiveCheckBox) viewGroup.getChildAt(3);
original.setOnCheckedChangeListener(this);
translated.setOnCheckedChangeListener(this);
rewrite.setOnCheckedChangeListener(this);
}
@Override
public void onCheckedChanged(SensitiveCheckBox view, boolean isChecked, boolean fromUser) {
if (fromUser) {
int row = getAdapterPosition();
if (row < 0) {
return;
}
int column;
if (view == original) {
column = 0;
} else if (view == translated) {
column = 1;
} else {
column = 2;
}
mSelections[row][column] = !mSelections[row][column];
}
}
}
private clreplaced LanguageAdapter extends RecyclerView.Adapter<LanguageHolder> {
@Override
public LanguageHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new LanguageHolder(getLayoutInflater().inflate(R.layout.item_excluded_languages, parent, false));
}
@Override
public void onBindViewHolder(LanguageHolder holder, int position) {
holder.language.setText(LANGUAGE_STR_IDS[position]);
boolean[] selections = mSelections[position];
holder.original.setChecked(selections[0]);
holder.translated.setChecked(selections[1]);
holder.rewrite.setChecked(selections[2]);
}
@Override
public int gereplacedemCount() {
return ROW_COUNT;
}
}
}
19
Source : GalleryInfoScene.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
public final clreplaced GalleryInfoScene extends ToolbarScene {
public static final String KEY_GALLERY_DETAIL = "gallery_detail";
public static final String KEY_KEYS = "keys";
public static final String KEY_VALUES = "values";
private static final int INDEX_URL = 3;
private static final int INDEX_PARENT = 10;
/*---------------
Whole life cycle
---------------*/
@Nullable
private ArrayList<String> mKeys;
@Nullable
private ArrayList<String> mValues;
@Nullable
private EasyRecyclerView mRecyclerView;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void handlerArgs(Bundle args) {
if (args == null) {
return;
}
GalleryDetail gd = args.getParcelable(KEY_GALLERY_DETAIL);
if (gd == null) {
return;
}
if (mKeys == null || mValues == null) {
return;
}
Resources resources = getResources2();
replacedertUtils.replacedertNotNull(resources);
mKeys.add(resources.getString(R.string.header_key));
mValues.add(resources.getString(R.string.header_value));
mKeys.add(resources.getString(R.string.key_gid));
mValues.add(Long.toString(gd.gid));
mKeys.add(resources.getString(R.string.key_token));
mValues.add(gd.token);
mKeys.add(resources.getString(R.string.key_url));
mValues.add(EhUrl.getGalleryDetailUrl(gd.gid, gd.token));
mKeys.add(resources.getString(R.string.key_replacedle));
mValues.add(gd.replacedle);
mKeys.add(resources.getString(R.string.key_replacedle_jpn));
mValues.add(gd.replacedleJpn);
mKeys.add(resources.getString(R.string.key_thumb));
mValues.add(gd.thumb);
mKeys.add(resources.getString(R.string.key_category));
mValues.add(EhUtils.getCategory(gd.category));
mKeys.add(resources.getString(R.string.key_uploader));
mValues.add(gd.uploader);
mKeys.add(resources.getString(R.string.key_posted));
mValues.add(gd.posted);
mKeys.add(resources.getString(R.string.key_parent));
mValues.add(gd.parent);
mKeys.add(resources.getString(R.string.key_visible));
mValues.add(gd.visible);
mKeys.add(resources.getString(R.string.key_language));
mValues.add(gd.language);
mKeys.add(resources.getString(R.string.key_pages));
mValues.add(Integer.toString(gd.pages));
mKeys.add(resources.getString(R.string.key_size));
mValues.add(gd.size);
mKeys.add(resources.getString(R.string.key_favorite_count));
mValues.add(Integer.toString(gd.favoriteCount));
mKeys.add(resources.getString(R.string.key_favorited));
mValues.add(Boolean.toString(gd.isFavorited));
mKeys.add(resources.getString(R.string.key_rating_count));
mValues.add(Integer.toString(gd.ratingCount));
mKeys.add(resources.getString(R.string.key_rating));
mValues.add(Float.toString(gd.rating));
mKeys.add(resources.getString(R.string.key_torrents));
mValues.add(Integer.toString(gd.torrentCount));
mKeys.add(resources.getString(R.string.key_torrent_url));
mValues.add(gd.torrentUrl);
mKeys.add(resources.getString(R.string.favorite_name));
mValues.add(gd.favoriteName);
}
protected void onInit() {
mKeys = new ArrayList<>();
mValues = new ArrayList<>();
handlerArgs(getArguments());
}
protected void onRestore(@NonNull Bundle savedInstanceState) {
mKeys = savedInstanceState.getStringArrayList(KEY_KEYS);
mValues = savedInstanceState.getStringArrayList(KEY_VALUES);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList(KEY_KEYS, mKeys);
outState.putStringArrayList(KEY_VALUES, mValues);
}
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_gallery_info, container, false);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(view, R.id.recycler_view);
InfoAdapter adapter = new InfoAdapter();
mRecyclerView.setAdapter(adapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setPadding(context.getResources().getDimensionPixelOffset(R.dimen.keyline_margin));
mRecyclerView.addItemDecoration(decoration);
// mRecyclerView.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
mRecyclerView.setClipToPadding(false);
mRecyclerView.setHasFixedSize(true);
// mRecyclerView.setOnItemClickListener(this);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.gallery_info);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
}
public boolean onItemClick(int position) {
Context context = getContext2();
if (null != context && 0 != position && null != mValues) {
if (position == INDEX_PARENT) {
UrlOpener.openUrl(context, mValues.get(position), true);
} else {
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
cmb.setPrimaryClip(ClipData.newPlainText(null, mValues.get(position)));
if (position == INDEX_URL) {
// Save it to avoid detect the gallery
Settings.putClipboardTextHashCode(mValues.get(position).hashCode());
}
showTip(R.string.copied_to_clipboard, LENGTH_SHORT);
}
return true;
} else {
return false;
}
}
@Override
public void onNavigationClick() {
onBackPressed();
}
private static clreplaced InfoHolder extends RecyclerView.ViewHolder {
private final TextView key;
private final TextView value;
public InfoHolder(View itemView) {
super(itemView);
key = itemView.findViewById(R.id.key);
value = itemView.findViewById(R.id.value);
}
}
private clreplaced 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() {
mInflater = getLayoutInflater2();
replacedertUtils.replacedertNotNull(mInflater);
}
@Override
public int gereplacedemViewType(int position) {
if (position == 0) {
return TYPE_HEADER;
} else {
return TYPE_DATA;
}
}
@Override
public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new InfoHolder(mInflater.inflate(viewType == TYPE_HEADER ? R.layout.item_gallery_info_header : R.layout.item_gallery_info_data, parent, false));
}
@Override
public void onBindViewHolder(InfoHolder holder, int position) {
if (mKeys != null && mValues != null) {
holder.key.setText(mKeys.get(position));
holder.value.setText(mValues.get(position));
holder.itemView.setEnabled(position != 0);
holder.itemView.setOnClickListener(v -> onItemClick(position));
}
}
@Override
public int gereplacedemCount() {
return mKeys == null || mValues == null ? 0 : Math.min(mKeys.size(), mValues.size());
}
}
}
19
Source : GalleryCommentsScene.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
public boolean onItemClick(EasyRecyclerView parent, View view, int position) {
MainActivity activity = getActivity2();
if (null == activity) {
return false;
}
RecyclerView.ViewHolder holder = parent.getChildViewHolder(view);
if (holder instanceof ActualCommentHolder) {
ActualCommentHolder commentHolder = (ActualCommentHolder) holder;
ClickableSpan span = commentHolder.comment.getCurrentSpan();
commentHolder.comment.clearCurrentSpan();
if (span instanceof URLSpan) {
UrlOpener.openUrl(activity, ((URLSpan) span).getURL(), true);
} else {
showCommentDialog(position);
}
} else if (holder instanceof MoreCommentHolder && !mRefreshingComments && mAdapter != null) {
mRefreshingComments = true;
mShowAllComments = true;
mAdapter.notifyItemChanged(position);
String url = getGalleryDetailUrl();
if (url != null) {
// Request
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_GET_GALLERY_DETAIL).setArgs(url).setCallback(new RefreshCommentListener(activity, activity.getStageId(), getTag()));
EhApplication.getEhClient(activity).execute(request);
}
}
return true;
}
19
Source : GalleryInfoScene.java
with Apache License 2.0
from duzhaokun123
with Apache License 2.0
from duzhaokun123
public final clreplaced GalleryInfoScene extends ToolbarScene {
public static final String KEY_GALLERY_DETAIL = "gallery_detail";
public static final String KEY_KEYS = "keys";
public static final String KEY_VALUES = "values";
private static final int INDEX_URL = 3;
private static final int INDEX_PARENT = 10;
/*---------------
Whole life cycle
---------------*/
@Nullable
private ArrayList<String> mKeys;
@Nullable
private ArrayList<String> mValues;
@Nullable
private EasyRecyclerView mRecyclerView;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void handlerArgs(Bundle args) {
if (args == null) {
return;
}
GalleryDetail gd = args.getParcelable(KEY_GALLERY_DETAIL);
if (gd == null) {
return;
}
if (mKeys == null || mValues == null) {
return;
}
mKeys.add(getString(R.string.header_key));
mValues.add(getString(R.string.header_value));
mKeys.add(getString(R.string.key_gid));
mValues.add(Long.toString(gd.gid));
mKeys.add(getString(R.string.key_token));
mValues.add(gd.token);
mKeys.add(getString(R.string.key_url));
mValues.add(EhUrl.getGalleryDetailUrl(gd.gid, gd.token));
mKeys.add(getString(R.string.key_replacedle));
mValues.add(gd.replacedle);
mKeys.add(getString(R.string.key_replacedle_jpn));
mValues.add(gd.replacedleJpn);
mKeys.add(getString(R.string.key_thumb));
mValues.add(gd.thumb);
mKeys.add(getString(R.string.key_category));
mValues.add(EhUtils.getCategory(gd.category));
mKeys.add(getString(R.string.key_uploader));
mValues.add(gd.uploader);
mKeys.add(getString(R.string.key_posted));
mValues.add(gd.posted);
mKeys.add(getString(R.string.key_parent));
mValues.add(gd.parent);
mKeys.add(getString(R.string.key_visible));
mValues.add(gd.visible);
mKeys.add(getString(R.string.key_language));
mValues.add(gd.language);
mKeys.add(getString(R.string.key_pages));
mValues.add(Integer.toString(gd.pages));
mKeys.add(getString(R.string.key_size));
mValues.add(gd.size);
mKeys.add(getString(R.string.key_favorite_count));
mValues.add(Integer.toString(gd.favoriteCount));
mKeys.add(getString(R.string.key_favorited));
mValues.add(Boolean.toString(gd.isFavorited));
mKeys.add(getString(R.string.key_rating_count));
mValues.add(Integer.toString(gd.ratingCount));
mKeys.add(getString(R.string.key_rating));
mValues.add(Float.toString(gd.rating));
mKeys.add(getString(R.string.key_torrents));
mValues.add(Integer.toString(gd.torrentCount));
mKeys.add(getString(R.string.key_torrent_url));
mValues.add(gd.torrentUrl);
mKeys.add(getString(R.string.favorite_name));
mValues.add(gd.favoriteName);
}
protected void onInit() {
mKeys = new ArrayList<>();
mValues = new ArrayList<>();
handlerArgs(getArguments());
}
protected void onRestore(@NonNull Bundle savedInstanceState) {
mKeys = savedInstanceState.getStringArrayList(KEY_KEYS);
mValues = savedInstanceState.getStringArrayList(KEY_VALUES);
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList(KEY_KEYS, mKeys);
outState.putStringArrayList(KEY_VALUES, mValues);
}
@Override
public View onCreateViewWithToolbar(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_gallery_info, container, false);
Context context = getContext();
replacedertUtils.replacedertNotNull(context);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(view, R.id.recycler_view);
InfoAdapter adapter = new InfoAdapter();
mRecyclerView.setAdapter(adapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setPadding(context.getResources().getDimensionPixelOffset(R.dimen.keyline_margin));
mRecyclerView.addItemDecoration(decoration);
mRecyclerView.setClipToPadding(false);
mRecyclerView.setHasFixedSize(true);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.gallery_info);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
}
public boolean onItemClick(int position) {
Context context = getContext();
if (null != context && 0 != position && null != mValues) {
if (position == INDEX_PARENT) {
UrlOpener.openUrl(context, mValues.get(position), true);
} else {
ClipboardUtil.addTextToClipboard(mValues.get(position));
if (position == INDEX_URL) {
// Save it to avoid detect the gallery
Settings.putClipboardTextHashCode(mValues.get(position).hashCode());
}
showTip(R.string.copied_to_clipboard, LENGTH_SHORT);
}
return true;
} else {
return false;
}
}
@Override
public void onNavigationClick() {
onBackPressed();
}
private static clreplaced InfoHolder extends RecyclerView.ViewHolder {
private final TextView key;
private final TextView value;
public InfoHolder(View itemView) {
super(itemView);
key = itemView.findViewById(R.id.key);
value = itemView.findViewById(R.id.value);
}
}
private clreplaced 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() {
mInflater = getLayoutInflater();
replacedertUtils.replacedertNotNull(mInflater);
}
@Override
public int gereplacedemViewType(int position) {
if (position == 0) {
return TYPE_HEADER;
} else {
return TYPE_DATA;
}
}
@NonNull
@Override
public InfoHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new InfoHolder(mInflater.inflate(viewType == TYPE_HEADER ? R.layout.item_gallery_info_header : R.layout.item_gallery_info_data, parent, false));
}
@Override
public void onBindViewHolder(@NonNull InfoHolder holder, int position) {
if (mKeys != null && mValues != null) {
holder.key.setText(mKeys.get(position));
holder.value.setText(mValues.get(position));
holder.itemView.setEnabled(position != 0);
holder.itemView.setOnClickListener(v -> onItemClick(position));
}
}
@Override
public int gereplacedemCount() {
return mKeys == null || mValues == null ? 0 : Math.min(mKeys.size(), mValues.size());
}
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime());
v.setPadding(insets1.left, 0, insets1.right, 0);
View statusBarBackground = v.findViewById(R.id.status_bar_background);
statusBarBackground.getLayoutParams().height = insets1.top;
statusBarBackground.setBackgroundColor(AttrResources.getAttrColor(requireContext(), R.attr.colorPrimaryDark));
if (mRecyclerView != null) {
int keyline_margin = getResources().getDimensionPixelOffset(R.dimen.keyline_margin);
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), keyline_margin + insets1.bottom);
}
return WindowInsetsCompat.CONSUMED;
}
}
19
Source : HistoryScene.java
with Apache License 2.0
from axlecho
with Apache License 2.0
from axlecho
@Override
public boolean onItemLongClick(EasyRecyclerView parent, View view, int position, long id) {
final Context context = getContext2();
final MainActivity activity = getActivity2();
if (null == context || null == activity || null == mLazyList) {
return false;
}
final GalleryInfo gi = mLazyList.get(position);
new AlertDialog.Builder(context).setreplacedle(EhUtils.getSuitablereplacedle(gi)).sereplacedems(R.array.gallery_list_menu_entries, (dialog, which) -> {
switch(which) {
case // Download
0:
CommonOperations.startDownload(activity, gi, false);
break;
case // Favorites
1:
CommonOperations.addToFavorites(activity, gi);
showTip(R.string.add_to_favorite_success, LENGTH_SHORT);
break;
}
}).show();
return true;
}
19
Source : GalleryInfoScene.java
with Apache License 2.0
from axlecho
with Apache License 2.0
from axlecho
public final clreplaced GalleryInfoScene extends ToolbarScene implements EasyRecyclerView.OnItemClickListener {
public static final String KEY_GALLERY_DETAIL = "gallery_detail";
public static final String KEY_KEYS = "keys";
public static final String KEY_VALUES = "values";
/*---------------
Whole life cycle
---------------*/
@Nullable
private ArrayList<String> mKeys;
@Nullable
private ArrayList<String> mValues;
@Nullable
private EasyRecyclerView mRecyclerView;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void handlerArgs(Bundle args) {
if (args == null) {
return;
}
GalleryDetail gd = args.getParcelable(KEY_GALLERY_DETAIL);
if (gd == null) {
return;
}
if (mKeys == null || mValues == null) {
return;
}
Resources resources = getResources2();
replacedertUtils.replacedertNotNull(resources);
mKeys.add(resources.getString(R.string.header_key));
mValues.add(resources.getString(R.string.header_value));
mKeys.add(resources.getString(R.string.key_gid));
mValues.add(gd.gid);
mKeys.add(resources.getString(R.string.key_token));
mValues.add(gd.token);
mKeys.add(resources.getString(R.string.key_url));
mValues.add(EhUrl.getGalleryDetailUrl(gd.gid, gd.token));
mKeys.add(resources.getString(R.string.key_replacedle));
mValues.add(gd.replacedle);
mKeys.add(resources.getString(R.string.key_replacedle_jpn));
mValues.add(gd.replacedleJpn);
mKeys.add(resources.getString(R.string.key_thumb));
mValues.add(gd.thumb);
mKeys.add(resources.getString(R.string.key_category));
mValues.add(EhUtils.getCategory(gd.category));
mKeys.add(resources.getString(R.string.key_uploader));
mValues.add(gd.uploader);
mKeys.add(resources.getString(R.string.key_posted));
mValues.add(gd.posted);
mKeys.add(resources.getString(R.string.key_rating));
mValues.add(Float.toString(gd.rating));
mKeys.add(resources.getString(R.string.favorite_name));
mValues.add(gd.favoriteName);
}
protected void onInit() {
mKeys = new ArrayList<>();
mValues = new ArrayList<>();
handlerArgs(getArguments());
}
protected void onRestore(@NonNull Bundle savedInstanceState) {
mKeys = savedInstanceState.getStringArrayList(KEY_KEYS);
mValues = savedInstanceState.getStringArrayList(KEY_VALUES);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArrayList(KEY_KEYS, mKeys);
outState.putStringArrayList(KEY_VALUES, mValues);
}
@SuppressWarnings("deprecation")
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_gallery_info, container, false);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(view, R.id.recycler_view);
InfoAdapter adapter = new InfoAdapter();
mRecyclerView.setAdapter(adapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setPadding(context.getResources().getDimensionPixelOffset(R.dimen.keyline_margin));
mRecyclerView.addItemDecoration(decoration);
mRecyclerView.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
mRecyclerView.setClipToPadding(false);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setOnItemClickListener(this);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.gallery_info);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
}
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
Context context = getContext2();
if (null != context && 0 != position && null != mValues) {
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
cmb.setPrimaryClip(ClipData.newPlainText(null, mValues.get(position)));
if (position == 3) {
// Save it to avoid detect the gallery
Settings.putClipboardTextHashCode(mValues.get(position).hashCode());
}
showTip(R.string.copied_to_clipboard, LENGTH_SHORT);
return true;
} else {
return false;
}
}
@Override
public void onNavigationClick() {
onBackPressed();
}
private static clreplaced InfoHolder extends RecyclerView.ViewHolder {
private final TextView key;
private final TextView value;
public InfoHolder(View itemView) {
super(itemView);
key = (TextView) itemView.findViewById(R.id.key);
value = (TextView) itemView.findViewById(R.id.value);
}
}
private clreplaced 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() {
mInflater = getLayoutInflater2();
replacedertUtils.replacedertNotNull(mInflater);
}
@Override
public int gereplacedemViewType(int position) {
if (position == 0) {
return TYPE_HEADER;
} else {
return TYPE_DATA;
}
}
@Override
public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new InfoHolder(mInflater.inflate(viewType == TYPE_HEADER ? R.layout.item_gallery_info_header : R.layout.item_gallery_info_data, parent, false));
}
@Override
public void onBindViewHolder(InfoHolder holder, int position) {
if (mKeys != null && mValues != null) {
holder.key.setText(mKeys.get(position));
holder.value.setText(mValues.get(position));
holder.itemView.setEnabled(position != 0);
}
}
@Override
public int gereplacedemCount() {
return mKeys == null || mValues == null ? 0 : Math.min(mKeys.size(), mValues.size());
}
}
}
19
Source : GalleryCommentsScene.java
with Apache License 2.0
from axlecho
with Apache License 2.0
from axlecho
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
Activity activity = getActivity2();
if (null == activity) {
return false;
}
RecyclerView.ViewHolder holder = parent.getChildViewHolder(view);
if (holder instanceof CommentHolder) {
CommentHolder commentHolder = (CommentHolder) holder;
ClickableSpan span = commentHolder.comment.getCurrentSpan();
commentHolder.comment.clearCurrentSpan();
if (span instanceof URLSpan) {
UrlOpener.openUrl(activity, ((URLSpan) span).getURL(), true);
return true;
}
}
showCommentDialog(position);
return true;
}
19
Source : PluginsActivity.java
with Apache License 2.0
from axlecho
with Apache License 2.0
from axlecho
@Override
public boolean onItemClick(EasyRecyclerView easyRecyclerView, View view, int position, long id) {
return true;
}
18
Source : DirExplorer.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
File file = mFiles.get(position);
if (file == PARENT_DIR) {
file = mCurrentFile.getParentFile();
}
setCurrentFile(file);
return true;
}
18
Source : ContentLayout.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
public clreplaced ContentLayout extends FrameLayout {
private ProgressView mProgressView;
private TextView mTipView;
private ViewGroup mContentView;
private RefreshLayout mRefreshLayout;
private EasyRecyclerView mRecyclerView;
private FastScroller mFastScroller;
private ContentHelper mContentHelper;
private int mRecyclerViewOriginTop;
private int mRecyclerViewOriginBottom;
public ContentLayout(Context context) {
super(context);
init(context);
}
public ContentLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ContentLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
LayoutInflater.from(context).inflate(R.layout.widget_content_layout, this);
mProgressView = (ProgressView) findViewById(R.id.progress);
mTipView = (TextView) findViewById(R.id.tip);
mContentView = (ViewGroup) findViewById(R.id.content_view);
mRefreshLayout = (RefreshLayout) mContentView.findViewById(R.id.refresh_layout);
mFastScroller = (FastScroller) mContentView.findViewById(R.id.fast_scroller);
mRecyclerView = (EasyRecyclerView) mRefreshLayout.findViewById(R.id.recycler_view);
mFastScroller.attachToRecyclerView(mRecyclerView);
HandlerDrawable drawable = new HandlerDrawable();
drawable.setColor(AttrResources.getAttrColor(context, R.attr.widgetColorThemeAccent));
mFastScroller.setHandlerDrawable(drawable);
mRefreshLayout.setHeaderColorSchemeResources(R.color.loading_indicator_red, R.color.loading_indicator_purple, R.color.loading_indicator_blue, R.color.loading_indicator_cyan, R.color.loading_indicator_green, R.color.loading_indicator_yellow);
mRefreshLayout.setFooterColorSchemeResources(R.color.loading_indicator_red, R.color.loading_indicator_blue, R.color.loading_indicator_green, R.color.loading_indicator_orange);
mRecyclerViewOriginTop = mRecyclerView.getPaddingTop();
mRecyclerViewOriginBottom = mRecyclerView.getPaddingBottom();
}
@NonNull
public EasyRecyclerView getRecyclerView() {
return mRecyclerView;
}
public FastScroller getFastScroller() {
return mFastScroller;
}
public RefreshLayout getRefreshLayout() {
return mRefreshLayout;
}
public void setHelper(ContentHelper helper) {
mContentHelper = helper;
helper.init(this);
}
public void showFastScroll() {
if (!mFastScroller.isAttached()) {
mFastScroller.attachToRecyclerView(mRecyclerView);
}
}
public void hideFastScroll() {
mFastScroller.detachedFromRecyclerView();
}
public void setFitPaddingTop(int fitPaddingTop) {
// RecyclerView
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerViewOriginTop + fitPaddingTop, mRecyclerView.getPaddingRight(), mRecyclerView.getPaddingBottom());
// RefreshLayout
// TODO
mRefreshLayout.setProgressViewOffset(false, fitPaddingTop, fitPaddingTop + LayoutUtils.dp2pix(getContext(), 32));
}
public void setFitPaddingBottom(int fitPaddingBottom) {
// RecyclerView
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), mRecyclerViewOriginBottom + fitPaddingBottom);
}
@Override
protected Parcelable onSaveInstanceState() {
return mContentHelper.saveInstanceState(super.onSaveInstanceState());
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(mContentHelper.restoreInstanceState(state));
}
public abstract static clreplaced ContentHelper<E extends Parcelable> implements ViewTransition.OnShowViewListener {
private static final String TAG = ContentHelper.clreplaced.getSimpleName();
private static final int CHECK_DUPLICATE_RANGE = 50;
private static final String KEY_SUPER = "super";
private static final String KEY_SHOWN_VIEW = "shown_view";
private static final String KEY_TIP = "tip";
private static final String KEY_DATA = "data";
private static final String KEY_NEXT_ID = "next_id";
private static final String KEY_PAGE_DIVIDER = "page_divider";
private static final String KEY_START_PAGE = "start_page";
private static final String KEY_END_PAGE = "end_page";
private static final String KEY_PAGES = "pages";
public static final int TYPE_REFRESH = 0;
public static final int TYPE_PRE_PAGE = 1;
public static final int TYPE_PRE_PAGE_KEEP_POS = 2;
public static final int TYPE_NEXT_PAGE = 3;
public static final int TYPE_NEXT_PAGE_KEEP_POS = 4;
public static final int TYPE_SOMEWHERE = 5;
public static final int TYPE_REFRESH_PAGE = 6;
public static final int REFRESH_TYPE_HEADER = 0;
public static final int REFRESH_TYPE_FOOTER = 1;
public static final int REFRESH_TYPE_PROGRESS_VIEW = 2;
private ProgressView mProgressView;
private TextView mTipView;
private ViewGroup mContentView;
private RefreshLayout mRefreshLayout;
private EasyRecyclerView mRecyclerView;
private ViewTransition mViewTransition;
/**
* Store data
*/
private ArrayList<E> mData = new ArrayList<>();
/**
* Generate task id
*/
private final IntIdGenerator mIdGenerator = new IntIdGenerator();
/**
* Store the page divider index
*
* For example, the data contain page 3, page 4, page 5,
* page 3 size is 7, page 4 size is 8, page 5 size is 9,
* so <code>mPageDivider</code> contain 7, 15, 24.
*/
private IntList mPageDivider = new IntList();
/**
* The first page in <code>mData</code>
*/
private int mStartPage;
/**
* The last page + 1 in <code>mData</code>
*/
private int mEndPage;
/**
* The available page count.
*/
private int mPages;
private int mNextPage;
private int mCurrentTaskId;
private int mCurrentTaskType;
private int mCurrentTaskPage;
private int mNextPageScrollSize;
private String mEmptyString = "No hint";
private final RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (!mRefreshLayout.isRefreshing() && mRefreshLayout.isAlmostBottom() && mEndPage < mPages) {
// Get next page
mRefreshLayout.setFooterRefreshing(true);
mOnRefreshListener.onFooterRefresh();
}
}
};
private final RefreshLayout.OnRefreshListener mOnRefreshListener = new RefreshLayout.OnRefreshListener() {
@Override
public void onHeaderRefresh() {
if (mStartPage > 0) {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_PRE_PAGE_KEEP_POS;
mCurrentTaskPage = mStartPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
doRefresh();
}
}
@Override
public void onFooterRefresh() {
if (mEndPage < mPages) {
// Get next page
// Fill pages before NextPage with empty list
while (mNextPage > mEndPage && mEndPage < mPages) {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
onGetPageData(mCurrentTaskId, mPages, mNextPage, Collections.emptyList());
}
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else if (mEndPage == mPages) {
// Refresh last page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_REFRESH_PAGE;
mCurrentTaskPage = mEndPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
Log.e(TAG, "Try to footer refresh, but mEndPage = " + mEndPage + ", mPages = " + mPages);
mRefreshLayout.setFooterRefreshing(false);
}
}
};
private final LayoutManagerUtils.OnScrollToPositionListener mOnScrollToPositionListener = opsition -> ContentHelper.this.onScrollToPosition(opsition);
// private final LayoutManagerUtils.OnScrollToPositionListener mOnScrollToPositionListener =
// new LayoutManagerUtils.OnScrollToPositionListener() {
// @Override
// public void onScrollToPosition(int position) {
// ContentHelper.this.onScrollToPosition(position);
// }
// };
private void init(ContentLayout contentLayout) {
mNextPageScrollSize = LayoutUtils.dp2pix(contentLayout.getContext(), 48);
mProgressView = contentLayout.mProgressView;
mTipView = contentLayout.mTipView;
mContentView = contentLayout.mContentView;
mRefreshLayout = contentLayout.mRefreshLayout;
mRecyclerView = contentLayout.mRecyclerView;
Drawable drawable = DrawableManager.getVectorDrawable(getContext(), R.drawable.big_sad_pandroid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
mTipView.setCompoundDrawables(null, drawable, null, null);
mViewTransition = new ViewTransition(mContentView, mProgressView, mTipView);
mViewTransition.setOnShowViewListener(this);
mRecyclerView.addOnScrollListener(mOnScrollListener);
mRefreshLayout.setOnRefreshListener(mOnRefreshListener);
mTipView.setOnClickListener(// 刷新页面
v -> refresh());
// mTipView.setOnClickListener(new OnClickListener() {
// @Override
// public void onClick(View v) {
// refresh();
// }
// });
}
/**
* Call {@link #onGetPageData(int, int, int, List)} when get data
*
* @param taskId task id
* @param page the page to get
*/
protected abstract void getPageData(int taskId, int type, int page);
protected abstract Context getContext();
protected abstract void notifyDataSetChanged();
protected abstract void notifyItemRangeRemoved(int positionStart, int itemCount);
protected abstract void notifyItemRangeInserted(int positionStart, int itemCount);
protected void onScrollToPosition(int postion) {
}
@Override
public void onShowView(View hiddenView, View shownView) {
}
public int getShownViewIndex() {
return mViewTransition.getShownViewIndex();
}
public void setRefreshLayoutEnable(boolean enable) {
mRefreshLayout.setEnabled(enable);
}
public void setEnable(boolean enable) {
mRefreshLayout.setEnabled(enable);
}
public void setEmptyString(String str) {
mEmptyString = str;
}
public List<E> getData() {
return mData;
}
/**
* @throws IndexOutOfBoundsException
* if {@code location < 0 || location >= size()}
*/
public E getDataAt(int location) {
return mData.get(location);
}
@Nullable
public E getDataAtEx(int location) {
if (location >= 0 && location < mData.size()) {
return mData.get(location);
} else {
return null;
}
}
public int size() {
return mData.size();
}
public boolean isCurrentTask(int taskId) {
return mCurrentTaskId == taskId;
}
public int getPages() {
return mPages;
}
public void addAt(int index, E data) {
mData.add(index, data);
onAddData(data);
for (int i = 0, n = mPageDivider.size(); i < n; i++) {
int divider = mPageDivider.get(i);
if (index < divider) {
mPageDivider.set(i, divider + 1);
}
}
notifyItemRangeInserted(index, 1);
}
public void removeAt(int index) {
E data = mData.remove(index);
onRemoveData(data);
for (int i = 0, n = mPageDivider.size(); i < n; i++) {
int divider = mPageDivider.get(i);
if (index < divider) {
mPageDivider.set(i, divider - 1);
}
}
notifyItemRangeRemoved(index, 1);
}
protected abstract boolean isDuplicate(E d1, E d2);
private void removeDuplicateData(List<E> data, int start, int end) {
start = Math.max(0, start);
end = Math.min(mData.size(), end);
for (Iterator<E> iterator = data.iterator(); iterator.hasNext(); ) {
E d = iterator.next();
for (int i = start; i < end; i++) {
if (isDuplicate(d, mData.get(i))) {
iterator.remove();
break;
}
}
}
}
protected void onAddData(E data) {
}
protected void onAddData(List<E> data) {
}
protected void onRemoveData(E data) {
}
protected void onRemoveData(List<E> data) {
}
protected void onClearData() {
}
public void onGetPageData(int taskId, int pages, int nextPage, List<E> data) {
if (mCurrentTaskId == taskId) {
int dataSize;
switch(mCurrentTaskType) {
case TYPE_REFRESH:
mStartPage = 0;
mEndPage = 1;
mPages = pages;
mNextPage = nextPage;
mPageDivider.clear();
mPageDivider.add(data.size());
if (data.isEmpty()) {
mData.clear();
onClearData();
notifyDataSetChanged();
if (true || mEndPage >= mPages) {
// Not found
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showProgressBar();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.clear();
onClearData();
mData.addAll(data);
onAddData(data);
notifyDataSetChanged();
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
// RecyclerView scroll
if (mRecyclerView.isAttachedToWindow()) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
break;
case TYPE_PRE_PAGE:
case TYPE_PRE_PAGE_KEEP_POS:
removeDuplicateData(data, 0, CHECK_DUPLICATE_RANGE);
dataSize = data.size();
for (int i = 0, n = mPageDivider.size(); i < n; i++) {
mPageDivider.set(i, mPageDivider.get(i) + dataSize);
}
mPageDivider.add(0, dataSize);
mStartPage--;
mPages = Math.max(mEndPage, pages);
// replacedert mStartPage >= 0
if (data.isEmpty()) {
if (true || mStartPage <= 0) {
// OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mCurrentTaskType == TYPE_PRE_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll, to top
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
} else {
// Keep UI
// Get previous
mCurrentTaskId = mIdGenerator.nextId();
// Keep mCurrentTaskType
mCurrentTaskPage = mStartPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.addAll(0, data);
onAddData(data);
notifyItemRangeInserted(0, data.size());
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
if (mCurrentTaskType == TYPE_PRE_PAGE_KEEP_POS) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionProperly(mRecyclerView.getLayoutManager(), getContext(), dataSize - 1, mOnScrollToPositionListener);
} else {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
}
break;
case TYPE_NEXT_PAGE:
case TYPE_NEXT_PAGE_KEEP_POS:
removeDuplicateData(data, mData.size() - CHECK_DUPLICATE_RANGE, mData.size());
dataSize = data.size();
int oldDataSize = mData.size();
mPageDivider.add(oldDataSize + dataSize);
mEndPage++;
mNextPage = nextPage;
mPages = Math.max(mEndPage, pages);
if (data.isEmpty()) {
if (true || mEndPage >= mPages) {
// OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mCurrentTaskType == TYPE_NEXT_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), oldDataSize, 0);
onScrollToPosition(oldDataSize);
}
}
} else {
// Keep UI
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
// Keep mCurrentTaskType
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.addAll(data);
onAddData(data);
notifyItemRangeInserted(oldDataSize, dataSize);
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mRecyclerView.isAttachedToWindow()) {
if (mCurrentTaskType == TYPE_NEXT_PAGE_KEEP_POS) {
mRecyclerView.stopScroll();
mRecyclerView.smoothScrollBy(0, mNextPageScrollSize);
} else {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), oldDataSize, 0);
onScrollToPosition(oldDataSize);
}
}
}
break;
case TYPE_SOMEWHERE:
mStartPage = mCurrentTaskPage;
mEndPage = mCurrentTaskPage + 1;
mNextPage = nextPage;
mPages = pages;
mPageDivider.clear();
mPageDivider.add(data.size());
if (data.isEmpty()) {
mData.clear();
onClearData();
notifyDataSetChanged();
if (true || mEndPage >= mPages) {
// Not found
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showProgressBar();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.clear();
onClearData();
mData.addAll(data);
onAddData(data);
notifyDataSetChanged();
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
break;
case TYPE_REFRESH_PAGE:
if (mCurrentTaskPage < mStartPage || mCurrentTaskPage >= mEndPage) {
Log.e(TAG, "TYPE_REFRESH_PAGE, but mCurrentTaskPage = " + mCurrentTaskPage + ", mStartPage = " + mStartPage + ", mEndPage = " + mEndPage);
break;
}
if (mCurrentTaskPage == mEndPage - 1) {
mNextPage = nextPage;
}
mPages = Math.max(mEndPage, pages);
int oldIndexStart = mCurrentTaskPage == mStartPage ? 0 : mPageDivider.get(mCurrentTaskPage - mStartPage - 1);
int oldIndexEnd = mPageDivider.get(mCurrentTaskPage - mStartPage);
List<E> toRemove = mData.subList(oldIndexStart, oldIndexEnd);
onRemoveData(toRemove);
toRemove.clear();
removeDuplicateData(data, oldIndexStart - CHECK_DUPLICATE_RANGE, oldIndexStart + CHECK_DUPLICATE_RANGE);
int newIndexStart = oldIndexStart;
int newIndexEnd = newIndexStart + data.size();
mData.addAll(oldIndexStart, data);
onAddData(data);
notifyDataSetChanged();
for (int i = mCurrentTaskPage - mStartPage, n = mPageDivider.size(); i < n; i++) {
mPageDivider.set(i, mPageDivider.get(i) - oldIndexEnd + newIndexEnd);
}
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
// RecyclerView scroll
if (newIndexEnd > oldIndexEnd && newIndexEnd > 0 && mRecyclerView.isAttachedToWindow()) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), newIndexEnd - 1, 0);
onScrollToPosition(newIndexEnd - 1);
}
}
break;
}
}
}
public void onGetException(int taskId, Exception e) {
if (mCurrentTaskId == taskId) {
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
String readableError;
if (e != null) {
e.printStackTrace();
readableError = ExceptionUtils.getReadableString(e);
} else {
readableError = getContext().getString(R.string.error_unknown);
}
if (mViewTransition.getShownViewIndex() == 0) {
Toast.makeText(getContext(), readableError, Toast.LENGTH_SHORT).show();
} else {
showText(readableError);
}
}
}
public void showContent() {
mViewTransition.showView(0);
}
private boolean isContentShowing() {
return mViewTransition.getShownViewIndex() == 0;
}
public void showProgressBar() {
showProgressBar(true);
}
public void showProgressBar(boolean animation) {
mViewTransition.showView(1, animation);
}
public void showText(CharSequence text) {
mTipView.setText(text);
mViewTransition.showView(2);
}
public void showEmptyString() {
showText(mEmptyString);
}
/**
* Be carefull
*/
public void doGetData(int type, int page, int refreshType) {
switch(refreshType) {
default:
case REFRESH_TYPE_HEADER:
showContent();
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
break;
case REFRESH_TYPE_FOOTER:
showContent();
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(true);
break;
case REFRESH_TYPE_PROGRESS_VIEW:
showProgressBar();
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
break;
}
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = type;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
private void doRefresh() {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_REFRESH;
mCurrentTaskPage = 0;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
/**
* Lisk {@link #refresh()}, but no animation when show progress bar
*/
public void firstRefresh() {
showProgressBar(false);
doRefresh();
}
/**
* Show progress bar first, than do refresh
*/
public void refresh() {
showProgressBar();
doRefresh();
}
private void cancelCurrentTask() {
mCurrentTaskId = mIdGenerator.nextId();
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
}
private int getPageStart(int page) {
if (mStartPage == page) {
return 0;
} else {
return mPageDivider.get(page - mStartPage - 1);
}
}
private int getPageEnd(int page) {
return mPageDivider.get(page - mStartPage);
}
private int getPageForPosition(int position) {
if (position < 0) {
return -1;
}
IntList pageDivider = mPageDivider;
for (int i = 0, n = pageDivider.size(); i < n; i++) {
if (position < pageDivider.get(i)) {
return i + mStartPage;
}
}
return -1;
}
public int getPageForTop() {
return getPageForPosition(LayoutManagerUtils.getFirstVisibleItemPosition(mRecyclerView.getLayoutManager()));
}
public int getPageForBottom() {
return getPageForPosition(LayoutManagerUtils.getLastVisibleItemPosition(mRecyclerView.getLayoutManager()));
}
public boolean canGoTo() {
return isContentShowing();
}
/**
* Check range first!
*
* @param page the target page
* @throws IndexOutOfBoundsException
*/
public void goTo(int page) throws IndexOutOfBoundsException {
if (page < 0 || page >= mPages) {
throw new IndexOutOfBoundsException("Page count is " + mPages + ", page is " + page);
} else if (page >= mStartPage && page < mEndPage) {
cancelCurrentTask();
int position = getPageStart(page);
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), position, 0);
onScrollToPosition(position);
} else if (page == mStartPage - 1) {
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_PRE_PAGE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else if (page == mEndPage) {
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(true);
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_SOMEWHERE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
}
private int mSavedDataId = IntIdGenerator.INVALID_ID;
protected Parcelable saveInstanceState(Parcelable superState) {
Bundle bundle = new Bundle();
bundle.putParcelable(KEY_SUPER, superState);
int shownView = mViewTransition.getShownViewIndex();
bundle.putInt(KEY_SHOWN_VIEW, shownView);
bundle.putString(KEY_TIP, mTipView.getText().toString());
// TODO It's a bad design
EhApplication app = (EhApplication) getContext().getApplicationContext();
if (mSavedDataId != IntIdGenerator.INVALID_ID) {
app.removeGlobalStuff(mSavedDataId);
mSavedDataId = IntIdGenerator.INVALID_ID;
}
mSavedDataId = app.putGlobalStuff(mData);
bundle.putInt(KEY_DATA, mSavedDataId);
bundle.putInt(KEY_NEXT_ID, mIdGenerator.nextId());
bundle.putParcelable(KEY_PAGE_DIVIDER, mPageDivider);
bundle.putInt(KEY_START_PAGE, mStartPage);
bundle.putInt(KEY_END_PAGE, mEndPage);
bundle.putInt(KEY_PAGES, mPages);
return bundle;
}
protected Parcelable restoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
mViewTransition.showView(bundle.getInt(KEY_SHOWN_VIEW), false);
mTipView.setText(bundle.getString(KEY_TIP));
mSavedDataId = bundle.getInt(KEY_DATA);
ArrayList<E> newData = null;
EhApplication app = (EhApplication) getContext().getApplicationContext();
if (mSavedDataId != IntIdGenerator.INVALID_ID) {
newData = (ArrayList<E>) app.removeGlobalStuff(mSavedDataId);
mSavedDataId = IntIdGenerator.INVALID_ID;
if (newData != null) {
mData = newData;
}
}
mIdGenerator.setNextId(bundle.getInt(KEY_NEXT_ID));
mPageDivider = bundle.getParcelable(KEY_PAGE_DIVIDER);
mStartPage = bundle.getInt(KEY_START_PAGE);
mEndPage = bundle.getInt(KEY_END_PAGE);
mPages = bundle.getInt(KEY_PAGES);
notifyDataSetChanged();
if (newData == null) {
mPageDivider.clear();
mStartPage = 0;
mEndPage = 0;
mPages = 0;
firstRefresh();
}
return bundle.getParcelable(KEY_SUPER);
} else {
return state;
}
}
}
}
18
Source : HistoryScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
if (null == mLazyList) {
return false;
}
Bundle args = new Bundle();
args.putString(GalleryDetailScene.KEY_ACTION, GalleryDetailScene.ACTION_GALLERY_INFO);
args.putParcelable(GalleryDetailScene.KEY_GALLERY_INFO, mLazyList.get(position));
Announcer announcer = new Announcer(GalleryDetailScene.clreplaced).setArgs(args);
View thumb;
if (null != (thumb = view.findViewById(R.id.thumb))) {
announcer.setTranHelper(new EnterGalleryDetailTransaction(thumb));
}
startScene(announcer);
return true;
}
18
Source : GalleryPreviewsScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
public clreplaced GalleryPreviewsScene extends ToolbarScene implements EasyRecyclerView.OnItemClickListener {
public static final String KEY_GALLERY_INFO = "gallery_info";
private final static String KEY_HAS_FIRST_REFRESH = "has_first_refresh";
/*---------------
Whole life cycle
---------------*/
@Nullable
private EhClient mClient;
@Nullable
private GalleryInfo mGalleryInfo;
/*---------------
View life cycle
---------------*/
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private GalleryPreviewAdapter mAdapter;
@Nullable
private GalleryPreviewHelper mHelper;
private boolean mHasFirstRefresh = false;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
mClient = EhApplication.getEhClient(context);
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void onInit() {
Bundle args = getArguments();
if (args == null) {
return;
}
mGalleryInfo = args.getParcelable(KEY_GALLERY_INFO);
}
private void onRestore(@NonNull Bundle savedInstanceState) {
mGalleryInfo = savedInstanceState.getParcelable(KEY_GALLERY_INFO);
mHasFirstRefresh = savedInstanceState.getBoolean(KEY_HAS_FIRST_REFRESH);
}
@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_GALLERY_INFO, mGalleryInfo);
}
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
ContentLayout contentLayout = (ContentLayout) inflater.inflate(R.layout.scene_gallery_previews, container, false);
contentLayout.hideFastScroll();
mRecyclerView = contentLayout.getRecyclerView();
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
Resources resources = context.getResources();
mAdapter = new GalleryPreviewAdapter();
mRecyclerView.setAdapter(mAdapter);
int columnWidth = resources.getDimensionPixelOffset(Settings.getThumbSizeResId());
AutoGridLayoutManager layoutManager = new AutoGridLayoutManager(context, columnWidth);
layoutManager.setStrategy(AutoGridLayoutManager.STRATEGY_SUITABLE_SIZE);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setClipToPadding(false);
mRecyclerView.setOnItemClickListener(this);
int padding = LayoutUtils.dp2pix(context, 4);
MarginItemDecoration decoration = new MarginItemDecoration(padding, padding, padding, padding, padding);
mRecyclerView.addItemDecoration(decoration);
decoration.applyPaddings(mRecyclerView);
mHelper = new GalleryPreviewHelper();
contentLayout.setHelper(mHelper);
// Only refresh for the first time
if (!mHasFirstRefresh) {
mHasFirstRefresh = true;
mHelper.firstRefresh();
}
return contentLayout;
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mHelper) {
if (1 == mHelper.getShownViewIndex()) {
mHasFirstRefresh = false;
}
}
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
mAdapter = null;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.gallery_previews);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public int getMenuResId() {
return R.menu.scene_gallery_previews;
}
@Override
public boolean onMenuItemClick(MenuItem item) {
Context context = getContext2();
if (null == context) {
return false;
}
int id = item.gereplacedemId();
switch(id) {
case R.id.action_go_to:
if (mHelper == null) {
return true;
}
int pages = mHelper.getPages();
if (pages > 0 && mHelper.canGoTo()) {
GoToDialogHelper helper = new GoToDialogHelper(pages, mHelper.getPageForTop());
AlertDialog dialog = new AlertDialog.Builder(context).setreplacedle(R.string.go_to).setView(R.layout.dialog_go_to).setPositiveButton(android.R.string.ok, null).create();
dialog.show();
helper.setDialog(dialog);
}
return true;
}
return false;
}
@Override
public void onNavigationClick() {
onBackPressed();
}
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
Context context = getContext2();
if (null != context && null != mHelper && null != mGalleryInfo) {
GalleryPreview p = mHelper.getDataAtEx(position);
if (p != null) {
Intent intent = new Intent(context, GalleryActivity.clreplaced);
intent.setAction(GalleryActivity.ACTION_EH);
intent.putExtra(GalleryActivity.KEY_GALLERY_INFO, mGalleryInfo);
intent.putExtra(GalleryActivity.KEY_PAGE, p.getPosition());
startActivity(intent);
}
}
return true;
}
private clreplaced GalleryPreviewHolder extends RecyclerView.ViewHolder {
public LoadImageView image;
public TextView text;
public GalleryPreviewHolder(View itemView) {
super(itemView);
image = (LoadImageView) itemView.findViewById(R.id.image);
text = (TextView) itemView.findViewById(R.id.text);
}
}
private clreplaced GalleryPreviewAdapter extends RecyclerView.Adapter<GalleryPreviewHolder> {
private final LayoutInflater mInflater;
public GalleryPreviewAdapter() {
mInflater = getLayoutInflater2();
replacedertUtils.replacedertNotNull(mInflater);
}
@Override
public GalleryPreviewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new GalleryPreviewHolder(mInflater.inflate(R.layout.item_gallery_preview, parent, false));
}
@Override
@SuppressLint("SetTextI18n")
public void onBindViewHolder(GalleryPreviewHolder holder, int position) {
if (null != mHelper) {
GalleryPreview preview = mHelper.getDataAtEx(position);
if (preview != null) {
preview.load(holder.image);
holder.text.setText(Integer.toString(preview.getPosition() + 1));
}
}
}
@Override
public int gereplacedemCount() {
return mHelper != null ? mHelper.size() : 0;
}
}
private clreplaced GalleryPreviewHelper extends ContentLayout.ContentHelper<GalleryPreview> {
@Override
protected void getPageData(final int taskId, int type, int page) {
MainActivity activity = getActivity2();
if (null == activity || null == mClient || null == mGalleryInfo) {
onGetException(taskId, new EhException(getString(R.string.error_cannot_find_gallery)));
return;
}
String url = EhUrl.getGalleryDetailUrl(mGalleryInfo.gid, mGalleryInfo.token, page, false);
EhRequest request = new EhRequest();
request.setMethod(EhClient.METHOD_GET_PREVIEW_SET);
request.setCallback(new GetPreviewSetListener(getContext(), activity.getStageId(), getTag(), taskId));
request.setArgs(url);
mClient.execute(request);
}
@Override
protected Context getContext() {
return GalleryPreviewsScene.this.getContext2();
}
@Override
protected void notifyDataSetChanged() {
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
protected boolean isDuplicate(GalleryPreview d1, GalleryPreview d2) {
return false;
}
}
private void onGetPreviewSetSuccess(Pair<PreviewSet, Integer> result, int taskId) {
if (null != mHelper && mHelper.isCurrentTask(taskId) && null != mGalleryInfo) {
PreviewSet previewSet = result.first;
int size = previewSet.size();
ArrayList<GalleryPreview> list = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
list.add(previewSet.getGalleryPreview(mGalleryInfo.gid, i));
}
mHelper.onGetPageData(taskId, result.second, 0, list);
}
}
private void onGetPreviewSetFailure(Exception e, int taskId) {
if (mHelper != null && mHelper.isCurrentTask(taskId)) {
mHelper.onGetException(taskId, e);
}
}
private static clreplaced GetPreviewSetListener extends EhCallback<GalleryPreviewsScene, Pair<PreviewSet, Integer>> {
private final int mTaskId;
public GetPreviewSetListener(Context context, int stageId, String sceneTag, int taskId) {
super(context, stageId, sceneTag);
mTaskId = taskId;
}
@Override
public void onSuccess(Pair<PreviewSet, Integer> result) {
GalleryPreviewsScene scene = getScene();
if (scene != null) {
scene.onGetPreviewSetSuccess(result, mTaskId);
}
}
@Override
public void onFailure(Exception e) {
GalleryPreviewsScene scene = getScene();
if (scene != null) {
scene.onGetPreviewSetFailure(e, mTaskId);
}
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryPreviewsScene;
}
}
private clreplaced GoToDialogHelper implements View.OnClickListener, DialogInterface.OnDismissListener {
private final int mPages;
private final int mCurrentPage;
@Nullable
private Slider mSlider;
@Nullable
private Dialog mDialog;
private GoToDialogHelper(int pages, int currentPage) {
mPages = pages;
mCurrentPage = currentPage;
}
public void setDialog(@NonNull AlertDialog dialog) {
mDialog = dialog;
((TextView) ViewUtils.$$(dialog, R.id.start)).setText(String.format(Locale.US, "%d", 1));
((TextView) ViewUtils.$$(dialog, R.id.end)).setText(String.format(Locale.US, "%d", mPages));
mSlider = (Slider) ViewUtils.$$(dialog, R.id.slider);
mSlider.setRange(1, mPages);
mSlider.setProgress(mCurrentPage + 1);
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(this);
dialog.setOnDismissListener(this);
}
@Override
public void onClick(View v) {
if (null == mSlider) {
return;
}
int page = mSlider.getProgress() - 1;
if (page >= 0 && page < mPages && mHelper != null) {
mHelper.goTo(page);
if (mDialog != null) {
mDialog.dismiss();
mDialog = null;
}
} else {
showTip(R.string.error_out_of_range, LENGTH_LONG);
}
}
@Override
public void onDismiss(DialogInterface dialog) {
mDialog = null;
mSlider = null;
}
}
}
18
Source : HostsActivity.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
public clreplaced HostsActivity extends ToolbarActivity implements EasyRecyclerView.OnItemClickListener, View.OnClickListener {
private static final String DIALOG_TAG_ADD_HOST = AddHostDialogFragment.clreplaced.getName();
private static final String DIALOG_TAG_EDIT_HOST = EditHostDialogFragment.clreplaced.getName();
private static final String KEY_HOST = "com.hippo.ehviewer.ui.HostsActivity.HOST";
private static final String KEY_IP = "com.hippo.ehviewer.ui.HostsActivity.IP";
private Hosts hosts;
private List<Pair<String, String>> data;
private EasyRecyclerView recyclerView;
private View tip;
private HostsAdapter adapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
hosts = EhApplication.getHosts(this);
data = hosts.getAll();
setContentView(R.layout.activity_hosts);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
recyclerView = findViewById(R.id.recycler_view);
tip = findViewById(R.id.tip);
FloatingActionButton fab = findViewById(R.id.fab);
adapter = new HostsAdapter();
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(this, R.attr.dividerColor), LayoutUtils.dp2pix(this, 1));
decoration.setShowLastDivider(true);
recyclerView.addItemDecoration(decoration);
recyclerView.setSelector(Ripple.generateRippleDrawable(this, !AttrResources.getAttrBoolean(this, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
recyclerView.setHasFixedSize(true);
recyclerView.setOnItemClickListener(this);
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(), recyclerView.getPaddingRight(), recyclerView.getPaddingBottom() + getResources().getDimensionPixelOffset(R.dimen.gallery_padding_bottom_fab));
fab.setOnClickListener(this);
recyclerView.setVisibility(data.isEmpty() ? View.GONE : View.VISIBLE);
tip.setVisibility(data.isEmpty() ? View.VISIBLE : View.GONE);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.gereplacedemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onItemClick(EasyRecyclerView easyRecyclerView, View view, int position, long id) {
Pair<String, String> pair = data.get(position);
Bundle args = new Bundle();
args.putString(KEY_HOST, pair.first);
args.putString(KEY_IP, pair.second);
DialogFragment fragment = new EditHostDialogFragment();
fragment.setArguments(args);
fragment.show(getSupportFragmentManager(), DIALOG_TAG_EDIT_HOST);
return true;
}
@Override
public void onClick(View v) {
new AddHostDialogFragment().show(getSupportFragmentManager(), DIALOG_TAG_ADD_HOST);
}
private void notifyHostsChanges() {
data = hosts.getAll();
recyclerView.setVisibility(data.isEmpty() ? View.GONE : View.VISIBLE);
tip.setVisibility(data.isEmpty() ? View.VISIBLE : View.GONE);
adapter.notifyDataSetChanged();
}
private clreplaced HostsHolder extends RecyclerView.ViewHolder {
public final TextView host;
public final TextView ip;
public HostsHolder(View itemView) {
super(itemView);
host = itemView.findViewById(R.id.host);
ip = itemView.findViewById(R.id.ip);
}
}
private clreplaced HostsAdapter extends RecyclerView.Adapter<HostsHolder> {
private final LayoutInflater inflater = getLayoutInflater();
@NonNull
@Override
public HostsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new HostsHolder(inflater.inflate(R.layout.item_hosts, parent, false));
}
@Override
public void onBindViewHolder(@NonNull HostsHolder holder, int position) {
Pair<String, String> pair = data.get(position);
holder.host.setText(pair.first);
holder.ip.setText(pair.second);
}
@Override
public int gereplacedemCount() {
return data.size();
}
}
public abstract static clreplaced HostDialogFragment extends DialogFragment {
private TextView host;
private TextView ip;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_hosts, null, false);
host = view.findViewById(R.id.host);
ip = view.findViewById(R.id.ip);
Bundle arguments = getArguments();
if (savedInstanceState == null && arguments != null) {
host.setText(arguments.getString(KEY_HOST));
ip.setText(arguments.getString(KEY_IP));
}
AlertDialog.Builder builder = new AlertDialog.Builder(getContext()).setView(view);
onCreateDialogBuilder(builder);
AlertDialog dialog = builder.create();
dialog.setOnShowListener(d -> onCreateDialog((AlertDialog) d));
return dialog;
}
protected abstract void onCreateDialogBuilder(AlertDialog.Builder builder);
protected abstract void onCreateDialog(AlertDialog dialog);
protected void put(AlertDialog dialog) {
TextView host = dialog.findViewById(R.id.host);
TextView ip = dialog.findViewById(R.id.ip);
String hostString = host.getText().toString().trim().toLowerCase(Locale.US);
String ipString = ip.getText().toString().trim();
if (!Hosts.isValidHost(hostString)) {
TextInputLayout hostInputLayout = dialog.findViewById(R.id.host_input_layout);
hostInputLayout.setError(getContext().getString(R.string.invalid_host));
return;
}
if (!Hosts.isValidIp(ipString)) {
TextInputLayout ipInputLayout = dialog.findViewById(R.id.ip_input_layout);
ipInputLayout.setError(getContext().getString(R.string.invalid_ip));
return;
}
HostsActivity activity = (HostsActivity) dialog.getOwnerActivity();
activity.hosts.put(hostString, ipString);
activity.notifyHostsChanges();
dialog.dismiss();
}
protected void delete(AlertDialog dialog) {
TextView host = dialog.findViewById(R.id.host);
String hostString = host.getText().toString().trim().toLowerCase(Locale.US);
HostsActivity activity = (HostsActivity) dialog.getOwnerActivity();
activity.hosts.delete(hostString);
activity.notifyHostsChanges();
dialog.dismiss();
}
}
public static clreplaced AddHostDialogFragment extends HostDialogFragment {
@Override
protected void onCreateDialogBuilder(AlertDialog.Builder builder) {
builder.setreplacedle(R.string.add_host);
builder.setPositiveButton(R.string.add_host_add, null);
}
@Override
protected void onCreateDialog(AlertDialog dialog) {
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v -> put(dialog));
}
}
public static clreplaced EditHostDialogFragment extends HostDialogFragment {
@Override
protected void onCreateDialogBuilder(AlertDialog.Builder builder) {
builder.setreplacedle(R.string.edit_host);
builder.setPositiveButton(R.string.edit_host_confirm, null);
builder.setNegativeButton(R.string.edit_host_delete, null);
}
@Override
protected void onCreateDialog(AlertDialog dialog) {
dialog.findViewById(R.id.host_input_layout).setEnabled(false);
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v -> put(dialog));
dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setOnClickListener(v -> delete(dialog));
}
}
}
18
Source : FilterActivity.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
public clreplaced FilterActivity extends ToolbarActivity {
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private ViewTransition mViewTransition;
@Nullable
private FilterAdapter mAdapter;
@Nullable
private FilterList mFilterList;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_filter);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
mFilterList = new FilterList();
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(this, R.id.recycler_view);
TextView tip = (TextView) ViewUtils.$$(this, R.id.tip);
mViewTransition = new ViewTransition(mRecyclerView, tip);
Drawable drawable = DrawableManager.getVectorDrawable(this, R.drawable.big_filter);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
mAdapter = new FilterAdapter();
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setClipToPadding(false);
mRecyclerView.setClipChildren(false);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.hasFixedSize();
mRecyclerView.sereplacedemAnimator(null);
updateView(false);
}
private void updateView(boolean animation) {
if (null == mViewTransition) {
return;
}
if (null == mFilterList || 0 == mFilterList.size()) {
mViewTransition.showView(1, animation);
} else {
mViewTransition.showView(0, animation);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mRecyclerView = null;
mViewTransition = null;
mAdapter = null;
mFilterList = null;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.activity_filter, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.gereplacedemId()) {
case android.R.id.home:
finish();
return true;
case R.id.action_add:
showAddFilterDialog();
return true;
case R.id.action_tip:
showTipDialog();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void showTipDialog() {
new AlertDialog.Builder(this).setreplacedle(R.string.filter).setMessage(R.string.filter_tip).show();
}
private void showAddFilterDialog() {
AlertDialog dialog = new AlertDialog.Builder(this).setreplacedle(R.string.add_filter).setView(R.layout.dialog_add_filter).setPositiveButton(R.string.add, null).show();
AddFilterDialogHelper helper = new AddFilterDialogHelper();
helper.setDialog(dialog);
}
private void showDeleteFilterDialog(final Filter filter) {
String message = getString(R.string.delete_filter, filter.text);
new AlertDialog.Builder(this).setMessage(message).setPositiveButton(R.string.delete, (dialog, which) -> {
if (DialogInterface.BUTTON_POSITIVE != which || null == mFilterList) {
return;
}
mFilterList.delete(filter);
if (null != mAdapter) {
mAdapter.notifyDataSetChanged();
}
updateView(true);
}).show();
}
private clreplaced AddFilterDialogHelper implements View.OnClickListener {
@Nullable
private AlertDialog mDialog;
@Nullable
private Spinner mSpinner;
@Nullable
private TextInputLayout mInputLayout;
@Nullable
private EditText mEditText;
public void setDialog(AlertDialog dialog) {
mDialog = dialog;
mSpinner = (Spinner) ViewUtils.$$(dialog, R.id.spinner);
mInputLayout = (TextInputLayout) ViewUtils.$$(dialog, R.id.text_input_layout);
mEditText = mInputLayout.getEditText();
View button = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (null != button) {
button.setOnClickListener(this);
}
}
@Override
public void onClick(View v) {
if (null == mFilterList || null == mDialog || null == mSpinner || null == mInputLayout || null == mEditText) {
return;
}
String text = mEditText.getText().toString().trim();
if (TextUtils.isEmpty(text)) {
mInputLayout.setError(getString(R.string.text_is_empty));
return;
} else {
mInputLayout.setError(null);
}
int mode = mSpinner.getSelectedItemPosition();
Filter filter = new Filter();
filter.mode = mode;
filter.text = text;
mFilterList.add(filter);
if (null != mAdapter) {
mAdapter.notifyDataSetChanged();
}
updateView(true);
mDialog.dismiss();
mDialog = null;
mSpinner = null;
mInputLayout = null;
mEditText = null;
}
}
private clreplaced FilterHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final TextView text;
private final ImageView icon;
public FilterHolder(View itemView) {
super(itemView);
text = (TextView) ViewUtils.$$(itemView, R.id.text);
icon = itemView.findViewById(R.id.icon);
if (null != icon) {
icon.setOnClickListener(this);
}
// click on the filter text to enable/disable it
text.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int position = getAdapterPosition();
if (position < 0 || null == mFilterList) {
return;
}
Filter filter = mFilterList.get(position);
if (FilterList.MODE_HEADER != filter.mode) {
if (v instanceof ImageView) {
showDeleteFilterDialog(filter);
} else if (v instanceof TextView) {
mFilterList.trigger(filter);
// for updating delete line on filter text
mAdapter.notifyItemChanged(getAdapterPosition());
}
}
}
}
private clreplaced FilterAdapter extends RecyclerView.Adapter<FilterHolder> {
private static final int TYPE_ITEM = 0;
private static final int TYPE_HEADER = 1;
@Override
public int gereplacedemViewType(int position) {
if (null == mFilterList) {
return TYPE_ITEM;
}
if (mFilterList.get(position).mode == FilterList.MODE_HEADER) {
return TYPE_HEADER;
} else {
return TYPE_ITEM;
}
}
@Override
public FilterHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layoutId;
switch(viewType) {
default:
case TYPE_ITEM:
layoutId = R.layout.item_filter;
break;
case TYPE_HEADER:
layoutId = R.layout.item_filter_header;
break;
}
FilterHolder holder = new FilterHolder(getLayoutInflater().inflate(layoutId, parent, false));
if (R.layout.item_filter == layoutId) {
holder.icon.setImageDrawable(DrawableManager.getVectorDrawable(FilterActivity.this, R.drawable.v_delete_x24));
}
return holder;
}
@Override
public void onBindViewHolder(FilterHolder holder, int position) {
if (null == mFilterList) {
return;
}
Filter filter = mFilterList.get(position);
if (FilterList.MODE_HEADER == filter.mode) {
holder.text.setText(filter.text);
} else {
holder.text.setText(filter.text);
// add a delete line if the filter is disabled
if (!filter.enable) {
holder.text.setPaintFlags(holder.text.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
} else {
holder.text.setPaintFlags(holder.text.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
}
}
}
@Override
public int gereplacedemCount() {
return null != mFilterList ? mFilterList.size() : 0;
}
}
private clreplaced FilterList {
public static final int MODE_HEADER = -1;
private final EhFilter mEhFilter;
private final List<Filter> mreplacedleFilterList;
private final List<Filter> mUploaderFilterList;
private final List<Filter> mTagFilterList;
private final List<Filter> mTagNamespaceFilterList;
private Filter mreplacedleHeader;
private Filter mUploaderHeader;
private Filter mTagHeader;
private Filter mTagNamespaceHeader;
public FilterList() {
mEhFilter = EhFilter.getInstance();
mreplacedleFilterList = mEhFilter.getreplacedleFilterList();
mUploaderFilterList = mEhFilter.getUploaderFilterList();
mTagFilterList = mEhFilter.getTagFilterList();
mTagNamespaceFilterList = mEhFilter.getTagNamespaceFilterList();
}
public int size() {
int count = 0;
int size = mreplacedleFilterList.size();
count += 0 == size ? 0 : size + 1;
size = mUploaderFilterList.size();
count += 0 == size ? 0 : size + 1;
size = mTagFilterList.size();
count += 0 == size ? 0 : size + 1;
size = mTagNamespaceFilterList.size();
count += 0 == size ? 0 : size + 1;
return count;
}
private Filter getreplacedleHeader() {
if (null == mreplacedleHeader) {
mreplacedleHeader = new Filter();
mreplacedleHeader.mode = MODE_HEADER;
mreplacedleHeader.text = getString(R.string.filter_replacedle);
}
return mreplacedleHeader;
}
private Filter getUploaderHeader() {
if (null == mUploaderHeader) {
mUploaderHeader = new Filter();
mUploaderHeader.mode = MODE_HEADER;
mUploaderHeader.text = getString(R.string.filter_uploader);
}
return mUploaderHeader;
}
private Filter getTagHeader() {
if (null == mTagHeader) {
mTagHeader = new Filter();
mTagHeader.mode = MODE_HEADER;
mTagHeader.text = getString(R.string.filter_tag);
}
return mTagHeader;
}
private Filter getTagNamespaceHeader() {
if (null == mTagNamespaceHeader) {
mTagNamespaceHeader = new Filter();
mTagNamespaceHeader.mode = MODE_HEADER;
mTagNamespaceHeader.text = getString(R.string.filter_tag_namespace);
}
return mTagNamespaceHeader;
}
public Filter get(int index) {
int size = mreplacedleFilterList.size();
if (0 != size) {
if (index == 0) {
return getreplacedleHeader();
} else if (index <= size) {
return mreplacedleFilterList.get(index - 1);
} else {
index -= size + 1;
}
}
size = mUploaderFilterList.size();
if (0 != size) {
if (index == 0) {
return getUploaderHeader();
} else if (index <= size) {
return mUploaderFilterList.get(index - 1);
} else {
index -= size + 1;
}
}
size = mTagFilterList.size();
if (0 != size) {
if (index == 0) {
return getTagHeader();
} else if (index <= size) {
return mTagFilterList.get(index - 1);
} else {
index -= size + 1;
}
}
size = mTagNamespaceFilterList.size();
if (0 != size) {
if (index == 0) {
return getTagNamespaceHeader();
} else if (index <= size) {
return mTagNamespaceFilterList.get(index - 1);
} else {
index -= size + 1;
}
}
throw new IndexOutOfBoundsException();
}
public void add(Filter filter) {
mEhFilter.addFilter(filter);
}
public void delete(Filter filter) {
mEhFilter.deleteFilter(filter);
}
public void trigger(Filter filter) {
mEhFilter.triggerFilter(filter);
}
}
}
18
Source : BlackListActivity.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
public clreplaced BlackListActivity extends ToolbarActivity {
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private ViewTransition mViewTransition;
@Nullable
private BlackListAdapter mAdapter;
@Nullable
private BlackListList mblackListList;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_blacklist);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
mblackListList = new BlackListList();
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(this, R.id.recycler_view1);
TextView tip = (TextView) ViewUtils.$$(this, R.id.tip);
mViewTransition = new ViewTransition(mRecyclerView, tip);
Drawable drawable = DrawableManager.getVectorDrawable(this, R.drawable.big_filter);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
mAdapter = new BlackListAdapter();
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setClipToPadding(false);
mRecyclerView.setClipChildren(false);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.hasFixedSize();
mRecyclerView.sereplacedemAnimator(null);
updateView(false);
}
private void updateView(boolean animation) {
if (null == mViewTransition) {
return;
}
if (null == mblackListList || 0 == mblackListList.size()) {
mViewTransition.showView(1, animation);
} else {
mViewTransition.showView(0, animation);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mRecyclerView = null;
mViewTransition = null;
mAdapter = null;
mblackListList = null;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.activity_blick_list, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.gereplacedemId()) {
case android.R.id.home:
finish();
return true;
case R.id.action_add:
showAddBlackListDialog();
return true;
case R.id.action_tip:
showTipDialog();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void showTipDialog() {
new AlertDialog.Builder(this).setreplacedle(R.string.blacklist).setMessage(R.string.blacklist_tip).show();
}
private void showAddBlackListDialog() {
AlertDialog dialog = new AlertDialog.Builder(this).setreplacedle(R.string.add_blacklist).setView(R.layout.dialog_add_blacklist).setPositiveButton(R.string.add, null).show();
AddBlackListDialogHelper helper = new AddBlackListDialogHelper();
helper.setDialog(dialog);
}
private void showDeleteBlackListDialog(final BlackList blackList) {
String message = getString(R.string.delete_blacklist, blackList.badgayname);
new AlertDialog.Builder(this).setMessage(message).setPositiveButton(R.string.delete, (dialog, which) -> {
if (DialogInterface.BUTTON_POSITIVE != which || null == mblackListList) {
return;
}
mblackListList.delete(blackList);
if (null != mAdapter) {
mAdapter.notifyDataSetChanged();
}
updateView(true);
}).show();
}
private clreplaced AddBlackListDialogHelper implements View.OnClickListener {
@Nullable
private AlertDialog mDialog;
@Nullable
private Spinner mSpinner;
@Nullable
private TextInputLayout mInputLayout;
@Nullable
private EditText mEditText;
public void setDialog(AlertDialog dialog) {
mDialog = dialog;
mSpinner = (Spinner) ViewUtils.$$(dialog, R.id.spinner);
mInputLayout = (TextInputLayout) ViewUtils.$$(dialog, R.id.text_inputreason_layout);
mEditText = mInputLayout.getEditText();
View button = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (null != button) {
button.setOnClickListener(this);
}
}
@Override
public void onClick(View v) {
if (null == mblackListList || null == mDialog || null == mSpinner || null == mInputLayout || null == mEditText) {
return;
}
String text = mEditText.getText().toString().trim();
if (TextUtils.isEmpty(text)) {
mInputLayout.setError(getString(R.string.text_is_empty));
return;
} else {
mInputLayout.setError(null);
}
int mode = mSpinner.getSelectedItemPosition();
BlackList blackList = new BlackList();
blackList.badgayname = text;
blackList.add_time = TimeUtils.getTimeNow();
blackList.angrywith = "/手动添加/";
blackList.mode = 1;
mblackListList.add(blackList);
if (null != mAdapter) {
mAdapter.notifyDataSetChanged();
}
updateView(true);
mDialog.dismiss();
mDialog = null;
mSpinner = null;
mInputLayout = null;
mEditText = null;
}
}
private clreplaced BlackListHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final TextView text;
private final ImageView icon;
public BlackListHolder(View itemView) {
super(itemView);
text = (TextView) ViewUtils.$$(itemView, R.id.text);
icon = itemView.findViewById(R.id.icon);
if (null != icon) {
icon.setOnClickListener(this);
}
// click on the blacklist text to enable/disable it
text.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int position = getAdapterPosition();
if (position < 0 || null == mblackListList) {
return;
}
BlackList blackList = mblackListList.get(position);
if (v instanceof ImageView) {
showDeleteBlackListDialog(blackList);
} else if (v instanceof TextView) {
mAdapter.notifyItemChanged(getAdapterPosition());
}
}
}
private clreplaced BlackListAdapter extends RecyclerView.Adapter<BlackListHolder> {
private static final int TYPE_ITEM = 0;
private static final int TYPE_HEADER = 1;
@Override
public int gereplacedemViewType(int position) {
if (null == mblackListList) {
return TYPE_ITEM;
}
if (mblackListList.get(position).mode == BlackListList.MODE_HEADER) {
return TYPE_HEADER;
} else {
return TYPE_ITEM;
}
}
@Override
public BlackListHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layoutId;
switch(viewType) {
default:
case TYPE_ITEM:
layoutId = R.layout.item_blacklist;
break;
case TYPE_HEADER:
layoutId = R.layout.item_blacklist_header;
break;
}
BlackListHolder holder = new BlackListHolder(getLayoutInflater().inflate(layoutId, parent, false));
if (R.layout.item_blacklist == layoutId) {
holder.icon.setImageDrawable(DrawableManager.getVectorDrawable(BlackListActivity.this, R.drawable.v_delete_x24));
}
return holder;
}
@Override
public void onBindViewHolder(BlackListHolder holder, int position) {
if (null == mblackListList) {
return;
}
BlackList blackList = mblackListList.get(position);
if (BlackListList.MODE_HEADER == blackList.mode) {
holder.text.setText(blackList.badgayname);
} else {
holder.text.setText(blackList.badgayname);
holder.text.setPaintFlags(holder.text.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
}
}
@Override
public int gereplacedemCount() {
return null != mblackListList ? mblackListList.size() : 0;
}
}
private clreplaced BlackListList {
public static final int MODE_HEADER = -1;
private List<BlackList> mreplacedleBlackList;
private BlackList mreplacedleHeader;
public BlackListList() {
mreplacedleBlackList = EhDB.getAllBlackList();
}
public int size() {
int count = 0;
int size = mreplacedleBlackList.size();
count += 0 == size ? 0 : size + 1;
return count;
}
private BlackList getreplacedleHeader() {
if (null == mreplacedleHeader) {
mreplacedleHeader = new BlackList();
mreplacedleHeader.mode = MODE_HEADER;
mreplacedleHeader.badgayname = getString(R.string.blacklist_id);
}
return mreplacedleHeader;
}
public BlackList get(int index) {
int size = mreplacedleBlackList.size();
if (0 != size) {
if (index == 0) {
return getreplacedleHeader();
} else if (index <= size) {
return mreplacedleBlackList.get(index - 1);
} else {
index -= size + 1;
}
}
throw new IndexOutOfBoundsException();
}
public void add(BlackList blackList) {
EhDB.insertBlackList(blackList);
mreplacedleBlackList.add(blackList);
}
public void delete(BlackList blackList) {
EhDB.deleteBlackList(blackList);
mreplacedleBlackList.remove(blackList);
}
}
}
18
Source : ContentLayout.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
public clreplaced ContentLayout extends FrameLayout {
private ProgressView mProgressView;
private TextView mTipView;
private ViewGroup mContentView;
private RefreshLayout mRefreshLayout;
private EasyRecyclerView mRecyclerView;
private FastScroller mFastScroller;
private ContentHelper<?> mContentHelper;
private int mRecyclerViewOriginTop;
private int mRecyclerViewOriginBottom;
public ContentLayout(Context context) {
super(context);
init(context);
}
public ContentLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ContentLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
LayoutInflater.from(context).inflate(R.layout.widget_content_layout, this);
mProgressView = findViewById(R.id.progress);
mTipView = findViewById(R.id.tip);
mContentView = findViewById(R.id.content_view);
mRefreshLayout = mContentView.findViewById(R.id.refresh_layout);
mFastScroller = mContentView.findViewById(R.id.fast_scroller);
mRecyclerView = mRefreshLayout.findViewById(R.id.recycler_view);
mFastScroller.attachToRecyclerView(mRecyclerView);
HandlerDrawable drawable = new HandlerDrawable();
drawable.setColor(AttrResources.getAttrColor(context, R.attr.widgetColorThemeAccent));
mFastScroller.setHandlerDrawable(drawable);
mRefreshLayout.setHeaderColorSchemeResources(R.color.loading_indicator_red, R.color.loading_indicator_purple, R.color.loading_indicator_blue, R.color.loading_indicator_cyan, R.color.loading_indicator_green, R.color.loading_indicator_yellow);
mRefreshLayout.setFooterColorSchemeResources(R.color.loading_indicator_red, R.color.loading_indicator_blue, R.color.loading_indicator_green, R.color.loading_indicator_orange);
mRecyclerViewOriginTop = mRecyclerView.getPaddingTop();
mRecyclerViewOriginBottom = mRecyclerView.getPaddingBottom();
}
@NonNull
public EasyRecyclerView getRecyclerView() {
return mRecyclerView;
}
public FastScroller getFastScroller() {
return mFastScroller;
}
public RefreshLayout getRefreshLayout() {
return mRefreshLayout;
}
public void setHelper(ContentHelper<?> helper) {
mContentHelper = helper;
helper.init(this);
}
public void showFastScroll() {
if (!mFastScroller.isAttached()) {
mFastScroller.attachToRecyclerView(mRecyclerView);
}
}
public void hideFastScroll() {
mFastScroller.detachedFromRecyclerView();
}
public void setFitPaddingTop(int fitPaddingTop) {
// RecyclerView
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerViewOriginTop + fitPaddingTop, mRecyclerView.getPaddingRight(), mRecyclerView.getPaddingBottom());
// RefreshLayout
// TODO
mRefreshLayout.setHeaderProgressViewOffset(true, 0, fitPaddingTop + LayoutUtils.dp2pix(getContext(), 32));
}
public void setFitPaddingBottom(int fitPaddingBottom) {
// RecyclerView
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), mRecyclerViewOriginBottom + fitPaddingBottom);
}
@Override
protected Parcelable onSaveInstanceState() {
return mContentHelper.saveInstanceState(super.onSaveInstanceState());
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(mContentHelper.restoreInstanceState(state));
}
public abstract static clreplaced ContentHelper<E extends Parcelable> implements ViewTransition.OnShowViewListener {
public static final int TYPE_REFRESH = 0;
public static final int TYPE_PRE_PAGE = 1;
public static final int TYPE_PRE_PAGE_KEEP_POS = 2;
public static final int TYPE_NEXT_PAGE = 3;
public static final int TYPE_NEXT_PAGE_KEEP_POS = 4;
public static final int TYPE_SOMEWHERE = 5;
public static final int TYPE_REFRESH_PAGE = 6;
public static final int REFRESH_TYPE_HEADER = 0;
public static final int REFRESH_TYPE_FOOTER = 1;
public static final int REFRESH_TYPE_PROGRESS_VIEW = 2;
private static final String TAG = ContentHelper.clreplaced.getSimpleName();
private static final int CHECK_DUPLICATE_RANGE = 50;
private static final String KEY_SUPER = "super";
private static final String KEY_SHOWN_VIEW = "shown_view";
private static final String KEY_TIP = "tip";
private static final String KEY_DATA = "data";
private static final String KEY_NEXT_ID = "next_id";
private static final String KEY_PAGE_DIVIDER = "page_divider";
private static final String KEY_START_PAGE = "start_page";
private static final String KEY_END_PAGE = "end_page";
private static final String KEY_PAGES = "pages";
/**
* Generate task id
*/
private final IntIdGenerator mIdGenerator = new IntIdGenerator();
private final LayoutManagerUtils.OnScrollToPositionListener mOnScrollToPositionListener = new LayoutManagerUtils.OnScrollToPositionListener() {
@Override
public void onScrollToPosition(int position) {
ContentHelper.this.onScrollToPosition(position);
}
};
private ProgressView mProgressView;
private TextView mTipView;
private ViewGroup mContentView;
private RefreshLayout mRefreshLayout;
private EasyRecyclerView mRecyclerView;
private ViewTransition mViewTransition;
/**
* Store data
*/
private ArrayList<E> mData = new ArrayList<>();
/**
* Store the page divider index
* <p>
* For example, the data contain page 3, page 4, page 5,
* page 3 size is 7, page 4 size is 8, page 5 size is 9,
* so <code>mPageDivider</code> contain 7, 15, 24.
*/
private IntList mPageDivider = new IntList();
/**
* The first page in <code>mData</code>
*/
private int mStartPage;
/**
* The last page + 1 in <code>mData</code>
*/
private int mEndPage;
/**
* The available page count.
*/
private int mPages;
private int mNextPage;
private int mCurrentTaskId;
private int mCurrentTaskType;
private int mCurrentTaskPage;
private int mNextPageScrollSize;
private String mEmptyString = "No hint";
private final RefreshLayout.OnRefreshListener mOnRefreshListener = new RefreshLayout.OnRefreshListener() {
@Override
public void onHeaderRefresh() {
if (mStartPage > 0) {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_PRE_PAGE_KEEP_POS;
mCurrentTaskPage = mStartPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
doRefresh();
}
}
@Override
public void onFooterRefresh() {
if (mEndPage < mPages) {
// Get next page
// Fill pages before NextPage with empty list
while (mNextPage > mEndPage && mEndPage < mPages) {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
onGetPageData(mCurrentTaskId, mPages, mNextPage, Collections.emptyList());
}
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else if (mEndPage == mPages) {
// Refresh last page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_REFRESH_PAGE;
mCurrentTaskPage = mEndPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
Log.e(TAG, "Try to footer refresh, but mEndPage = " + mEndPage + ", mPages = " + mPages);
mRefreshLayout.setFooterRefreshing(false);
}
}
};
private final RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (!mRefreshLayout.isRefreshing() && mRefreshLayout.isAlmostBottom() && mEndPage < mPages) {
// Get next page
mRefreshLayout.setFooterRefreshing(true);
mOnRefreshListener.onFooterRefresh();
}
}
};
private int mSavedDataId = IntIdGenerator.INVALID_ID;
private void init(ContentLayout contentLayout) {
mNextPageScrollSize = LayoutUtils.dp2pix(contentLayout.getContext(), 48);
mProgressView = contentLayout.mProgressView;
mTipView = contentLayout.mTipView;
mContentView = contentLayout.mContentView;
mRefreshLayout = contentLayout.mRefreshLayout;
mRecyclerView = contentLayout.mRecyclerView;
Drawable drawable = DrawableManager.getVectorDrawable(getContext(), R.drawable.big_sad_pandroid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
mTipView.setCompoundDrawables(null, drawable, null, null);
mViewTransition = new ViewTransition(mContentView, mProgressView, mTipView);
mViewTransition.setOnShowViewListener(this);
mRecyclerView.addOnScrollListener(mOnScrollListener);
mRefreshLayout.setOnRefreshListener(mOnRefreshListener);
mTipView.setOnClickListener(v -> refresh());
}
/**
* Call {@link #onGetPageData(int, int, int, List)} when get data
*
* @param taskId task id
* @param page the page to get
*/
protected abstract void getPageData(int taskId, int type, int page);
protected abstract Context getContext();
protected abstract void notifyDataSetChanged();
protected abstract void notifyItemRangeRemoved(int positionStart, int itemCount);
protected abstract void notifyItemRangeInserted(int positionStart, int itemCount);
protected void onScrollToPosition(int postion) {
}
@Override
public void onShowView(View hiddenView, View shownView) {
}
public int getShownViewIndex() {
return mViewTransition.getShownViewIndex();
}
public void setRefreshLayoutEnable(boolean enable) {
mRefreshLayout.setEnabled(enable);
}
public void setEnable(boolean enable) {
mRefreshLayout.setEnabled(enable);
}
public void setEmptyString(String str) {
mEmptyString = str;
}
public List<E> getData() {
return mData;
}
/**
* @throws IndexOutOfBoundsException if {@code location < 0 || location >= size()}
*/
public E getDataAt(int location) {
return mData.get(location);
}
@Nullable
public E getDataAtEx(int location) {
if (location >= 0 && location < mData.size()) {
return mData.get(location);
} else {
return null;
}
}
public int size() {
return mData.size();
}
public boolean isCurrentTask(int taskId) {
return mCurrentTaskId == taskId;
}
public int getPages() {
return mPages;
}
public void addAt(int index, E data) {
mData.add(index, data);
onAddData(data);
for (int i = 0, n = mPageDivider.size(); i < n; i++) {
int divider = mPageDivider.get(i);
if (index < divider) {
mPageDivider.set(i, divider + 1);
}
}
notifyItemRangeInserted(index, 1);
}
public void removeAt(int index) {
E data = mData.remove(index);
onRemoveData(data);
for (int i = 0, n = mPageDivider.size(); i < n; i++) {
int divider = mPageDivider.get(i);
if (index < divider) {
mPageDivider.set(i, divider - 1);
}
}
notifyItemRangeRemoved(index, 1);
}
protected abstract boolean isDuplicate(E d1, E d2);
private void removeDuplicateData(List<E> data, int start, int end) {
start = Math.max(0, start);
end = Math.min(mData.size(), end);
for (Iterator<E> iterator = data.iterator(); iterator.hasNext(); ) {
E d = iterator.next();
for (int i = start; i < end; i++) {
if (isDuplicate(d, mData.get(i))) {
iterator.remove();
break;
}
}
}
}
protected void onAddData(E data) {
}
protected void onAddData(List<E> data) {
}
protected void onRemoveData(E data) {
}
protected void onRemoveData(List<E> data) {
}
protected void onClearData() {
}
public void onGetPageData(int taskId, int pages, int nextPage, List<E> data) {
if (mCurrentTaskId == taskId) {
int dataSize;
switch(mCurrentTaskType) {
case TYPE_REFRESH:
mStartPage = 0;
mEndPage = 1;
mPages = pages;
mNextPage = nextPage;
mPageDivider.clear();
mPageDivider.add(data.size());
if (data.isEmpty()) {
mData.clear();
onClearData();
notifyDataSetChanged();
if (true || mEndPage >= mPages) {
// Not found
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showProgressBar();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.clear();
onClearData();
mData.addAll(data);
onAddData(data);
notifyDataSetChanged();
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
// RecyclerView scroll
if (mRecyclerView.isAttachedToWindow()) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
break;
case TYPE_PRE_PAGE:
case TYPE_PRE_PAGE_KEEP_POS:
removeDuplicateData(data, 0, CHECK_DUPLICATE_RANGE);
dataSize = data.size();
for (int i = 0, n = mPageDivider.size(); i < n; i++) {
mPageDivider.set(i, mPageDivider.get(i) + dataSize);
}
mPageDivider.add(0, dataSize);
mStartPage--;
mPages = Math.max(mEndPage, pages);
// replacedert mStartPage >= 0
if (data.isEmpty()) {
if (true || mStartPage <= 0) {
// OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mCurrentTaskType == TYPE_PRE_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll, to top
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
} else {
// Keep UI
// Get previous
mCurrentTaskId = mIdGenerator.nextId();
// Keep mCurrentTaskType
mCurrentTaskPage = mStartPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.addAll(0, data);
onAddData(data);
notifyItemRangeInserted(0, data.size());
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
if (mCurrentTaskType == TYPE_PRE_PAGE_KEEP_POS) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionProperly(mRecyclerView.getLayoutManager(), getContext(), dataSize - 1, mOnScrollToPositionListener);
} else {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
}
break;
case TYPE_NEXT_PAGE:
case TYPE_NEXT_PAGE_KEEP_POS:
removeDuplicateData(data, mData.size() - CHECK_DUPLICATE_RANGE, mData.size());
dataSize = data.size();
int oldDataSize = mData.size();
mPageDivider.add(oldDataSize + dataSize);
mEndPage++;
mNextPage = nextPage;
mPages = Math.max(mEndPage, pages);
if (data.isEmpty()) {
if (true || mEndPage >= mPages) {
// OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mCurrentTaskType == TYPE_NEXT_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), oldDataSize, 0);
onScrollToPosition(oldDataSize);
}
}
} else {
// Keep UI
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
// Keep mCurrentTaskType
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.addAll(data);
onAddData(data);
notifyItemRangeInserted(oldDataSize, dataSize);
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mRecyclerView.isAttachedToWindow()) {
if (mCurrentTaskType == TYPE_NEXT_PAGE_KEEP_POS) {
mRecyclerView.stopScroll();
mRecyclerView.smoothScrollBy(0, mNextPageScrollSize);
} else {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), oldDataSize, 0);
onScrollToPosition(oldDataSize);
}
}
}
break;
case TYPE_SOMEWHERE:
mStartPage = mCurrentTaskPage;
mEndPage = mCurrentTaskPage + 1;
mNextPage = nextPage;
mPages = pages;
mPageDivider.clear();
mPageDivider.add(data.size());
if (data.isEmpty()) {
mData.clear();
onClearData();
notifyDataSetChanged();
if (true || mEndPage >= mPages) {
// Not found
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showProgressBar();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.clear();
onClearData();
mData.addAll(data);
onAddData(data);
notifyDataSetChanged();
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
break;
case TYPE_REFRESH_PAGE:
if (mCurrentTaskPage < mStartPage || mCurrentTaskPage >= mEndPage) {
Log.e(TAG, "TYPE_REFRESH_PAGE, but mCurrentTaskPage = " + mCurrentTaskPage + ", mStartPage = " + mStartPage + ", mEndPage = " + mEndPage);
break;
}
if (mCurrentTaskPage == mEndPage - 1) {
mNextPage = nextPage;
}
mPages = Math.max(mEndPage, pages);
int oldIndexStart = mCurrentTaskPage == mStartPage ? 0 : mPageDivider.get(mCurrentTaskPage - mStartPage - 1);
int oldIndexEnd = mPageDivider.get(mCurrentTaskPage - mStartPage);
List<E> toRemove = mData.subList(oldIndexStart, oldIndexEnd);
onRemoveData(toRemove);
toRemove.clear();
removeDuplicateData(data, oldIndexStart - CHECK_DUPLICATE_RANGE, oldIndexStart + CHECK_DUPLICATE_RANGE);
int newIndexStart = oldIndexStart;
int newIndexEnd = newIndexStart + data.size();
mData.addAll(oldIndexStart, data);
onAddData(data);
notifyDataSetChanged();
for (int i = mCurrentTaskPage - mStartPage, n = mPageDivider.size(); i < n; i++) {
mPageDivider.set(i, mPageDivider.get(i) - oldIndexEnd + newIndexEnd);
}
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
// RecyclerView scroll
if (newIndexEnd > oldIndexEnd && newIndexEnd > 0 && mRecyclerView.isAttachedToWindow()) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), newIndexEnd - 1, 0);
onScrollToPosition(newIndexEnd - 1);
}
}
break;
}
}
}
public void onGetException(int taskId, Exception e) {
if (mCurrentTaskId == taskId) {
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
String readableError;
if (e != null) {
e.printStackTrace();
readableError = ExceptionUtils.getReadableString(e);
} else {
readableError = getContext().getString(R.string.error_unknown);
}
if (mViewTransition.getShownViewIndex() == 0) {
Toast.makeText(getContext(), readableError, Toast.LENGTH_SHORT).show();
} else {
showText(readableError);
}
}
}
public void showContent() {
mViewTransition.showView(0);
}
private boolean isContentShowing() {
return mViewTransition.getShownViewIndex() == 0;
}
public void showProgressBar() {
showProgressBar(true);
}
public void showProgressBar(boolean animation) {
mViewTransition.showView(1, animation);
}
public void showText(CharSequence text) {
mTipView.setText(text);
mViewTransition.showView(2);
}
public void showEmptyString() {
showText(mEmptyString);
}
/**
* Be carefull
*/
public void doGetData(int type, int page, int refreshType) {
switch(refreshType) {
default:
case REFRESH_TYPE_HEADER:
showContent();
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
break;
case REFRESH_TYPE_FOOTER:
showContent();
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(true);
break;
case REFRESH_TYPE_PROGRESS_VIEW:
showProgressBar();
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
break;
}
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = type;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
private void doRefresh() {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_REFRESH;
mCurrentTaskPage = 0;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
/**
* Lisk {@link #refresh()}, but no animation when show progress bar
*/
public void firstRefresh() {
showProgressBar(false);
doRefresh();
}
/**
* Show progress bar first, than do refresh
*/
public void refresh() {
showProgressBar();
doRefresh();
}
private void cancelCurrentTask() {
mCurrentTaskId = mIdGenerator.nextId();
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
}
private int getPageStart(int page) {
if (mStartPage == page) {
return 0;
} else {
return mPageDivider.get(page - mStartPage - 1);
}
}
private int getPageEnd(int page) {
return mPageDivider.get(page - mStartPage);
}
private int getPageForPosition(int position) {
if (position < 0) {
return -1;
}
IntList pageDivider = mPageDivider;
for (int i = 0, n = pageDivider.size(); i < n; i++) {
if (position < pageDivider.get(i)) {
return i + mStartPage;
}
}
return -1;
}
public int getPageForTop() {
return getPageForPosition(LayoutManagerUtils.getFirstVisibleItemPosition(mRecyclerView.getLayoutManager()));
}
public int getPageForBottom() {
return getPageForPosition(LayoutManagerUtils.getLastVisibleItemPosition(mRecyclerView.getLayoutManager()));
}
public boolean canGoTo() {
return isContentShowing();
}
/**
* Check range first!
*
* @param page the target page
* @throws IndexOutOfBoundsException
*/
public void goTo(int page) throws IndexOutOfBoundsException {
if (page < 0 || page >= mPages) {
throw new IndexOutOfBoundsException("Page count is " + mPages + ", page is " + page);
} else if (page >= mStartPage && page < mEndPage) {
cancelCurrentTask();
int position = getPageStart(page);
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), position, 0);
onScrollToPosition(position);
} else if (page == mStartPage - 1) {
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_PRE_PAGE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else if (page == mEndPage) {
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(true);
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_SOMEWHERE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
}
protected Parcelable saveInstanceState(Parcelable superState) {
Bundle bundle = new Bundle();
bundle.putParcelable(KEY_SUPER, superState);
int shownView = mViewTransition.getShownViewIndex();
bundle.putInt(KEY_SHOWN_VIEW, shownView);
bundle.putString(KEY_TIP, mTipView.getText().toString());
// TODO It's a bad design
EhApplication app = (EhApplication) getContext().getApplicationContext();
if (mSavedDataId != IntIdGenerator.INVALID_ID) {
app.removeGlobalStuff(mSavedDataId);
mSavedDataId = IntIdGenerator.INVALID_ID;
}
mSavedDataId = app.putGlobalStuff(mData);
bundle.putInt(KEY_DATA, mSavedDataId);
bundle.putInt(KEY_NEXT_ID, mIdGenerator.nextId());
bundle.putParcelable(KEY_PAGE_DIVIDER, mPageDivider);
bundle.putInt(KEY_START_PAGE, mStartPage);
bundle.putInt(KEY_END_PAGE, mEndPage);
bundle.putInt(KEY_PAGES, mPages);
return bundle;
}
protected Parcelable restoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
mViewTransition.showView(bundle.getInt(KEY_SHOWN_VIEW), false);
mTipView.setText(bundle.getString(KEY_TIP));
mSavedDataId = bundle.getInt(KEY_DATA);
ArrayList<E> newData = null;
EhApplication app = (EhApplication) getContext().getApplicationContext();
if (mSavedDataId != IntIdGenerator.INVALID_ID) {
newData = (ArrayList<E>) app.removeGlobalStuff(mSavedDataId);
mSavedDataId = IntIdGenerator.INVALID_ID;
if (newData != null) {
mData = newData;
}
}
mIdGenerator.setNextId(bundle.getInt(KEY_NEXT_ID));
mPageDivider = bundle.getParcelable(KEY_PAGE_DIVIDER);
mStartPage = bundle.getInt(KEY_START_PAGE);
mEndPage = bundle.getInt(KEY_END_PAGE);
mPages = bundle.getInt(KEY_PAGES);
notifyDataSetChanged();
if (newData == null) {
mPageDivider.clear();
mStartPage = 0;
mEndPage = 0;
mPages = 0;
firstRefresh();
}
return bundle.getParcelable(KEY_SUPER);
} else {
return state;
}
}
}
}
18
Source : GalleryPreviewsScene.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
public clreplaced GalleryPreviewsScene extends ToolbarScene {
public static final String KEY_GALLERY_INFO = "gallery_info";
private final static String KEY_HAS_FIRST_REFRESH = "has_first_refresh";
/*---------------
Whole life cycle
---------------*/
@Nullable
private EhClient mClient;
@Nullable
private GalleryInfo mGalleryInfo;
/*---------------
View life cycle
---------------*/
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private GalleryPreviewAdapter mAdapter;
@Nullable
private GalleryPreviewHelper mHelper;
private boolean mHasFirstRefresh = false;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
mClient = EhApplication.getEhClient(context);
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void onInit() {
Bundle args = getArguments();
if (args == null) {
return;
}
mGalleryInfo = args.getParcelable(KEY_GALLERY_INFO);
}
private void onRestore(@NonNull Bundle savedInstanceState) {
mGalleryInfo = savedInstanceState.getParcelable(KEY_GALLERY_INFO);
mHasFirstRefresh = savedInstanceState.getBoolean(KEY_HAS_FIRST_REFRESH);
}
@Override
public void onSaveInstanceState(@NonNull 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_GALLERY_INFO, mGalleryInfo);
}
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
ContentLayout contentLayout = (ContentLayout) inflater.inflate(R.layout.scene_gallery_previews, container, false);
contentLayout.hideFastScroll();
mRecyclerView = contentLayout.getRecyclerView();
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
Resources resources = context.getResources();
mAdapter = new GalleryPreviewAdapter();
mRecyclerView.setAdapter(mAdapter);
int columnWidth = resources.getDimensionPixelOffset(Settings.getThumbSizeResId());
AutoGridLayoutManager layoutManager = new AutoGridLayoutManager(context, columnWidth);
layoutManager.setStrategy(AutoGridLayoutManager.STRATEGY_SUITABLE_SIZE);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setClipToPadding(false);
int padding = LayoutUtils.dp2pix(context, 4);
MarginItemDecoration decoration = new MarginItemDecoration(padding, padding, padding, padding, padding);
mRecyclerView.addItemDecoration(decoration);
decoration.applyPaddings(mRecyclerView);
mHelper = new GalleryPreviewHelper();
contentLayout.setHelper(mHelper);
// Only refresh for the first time
if (!mHasFirstRefresh) {
mHasFirstRefresh = true;
mHelper.firstRefresh();
}
return contentLayout;
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mHelper) {
if (1 == mHelper.getShownViewIndex()) {
mHasFirstRefresh = false;
}
}
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
mAdapter = null;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.gallery_previews);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public int getMenuResId() {
return R.menu.scene_gallery_previews;
}
@Override
public boolean onMenuItemClick(MenuItem item) {
Context context = getContext2();
if (null == context) {
return false;
}
int id = item.gereplacedemId();
if (id == R.id.action_go_to) {
if (mHelper == null) {
return true;
}
int pages = mHelper.getPages();
if (pages > 0 && mHelper.canGoTo()) {
GoToDialogHelper helper = new GoToDialogHelper(pages, mHelper.getPageForTop());
AlertDialog dialog = new MaterialAlertDialogBuilder(context).setreplacedle(R.string.go_to).setView(R.layout.dialog_go_to).setPositiveButton(android.R.string.ok, null).create();
dialog.show();
helper.setDialog(dialog);
}
return true;
}
return false;
}
@Override
public void onNavigationClick() {
onBackPressed();
}
public boolean onItemClick(int position) {
Context context = getContext2();
if (null != context && null != mHelper && null != mGalleryInfo) {
GalleryPreview p = mHelper.getDataAtEx(position);
if (p != null) {
Intent intent = new Intent(context, GalleryActivity.clreplaced);
intent.setAction(GalleryActivity.ACTION_EH);
intent.putExtra(GalleryActivity.KEY_GALLERY_INFO, mGalleryInfo);
intent.putExtra(GalleryActivity.KEY_PAGE, p.getPosition());
startActivity(intent);
}
}
return true;
}
private void onGetPreviewSetSuccess(Pair<PreviewSet, Integer> result, int taskId) {
if (null != mHelper && mHelper.isCurrentTask(taskId) && null != mGalleryInfo) {
PreviewSet previewSet = result.first;
int size = previewSet.size();
ArrayList<GalleryPreview> list = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
list.add(previewSet.getGalleryPreview(mGalleryInfo.gid, i));
}
mHelper.onGetPageData(taskId, result.second, 0, list);
}
}
private void onGetPreviewSetFailure(Exception e, int taskId) {
if (mHelper != null && mHelper.isCurrentTask(taskId)) {
mHelper.onGetException(taskId, e);
}
}
private static clreplaced GetPreviewSetListener extends EhCallback<GalleryPreviewsScene, Pair<PreviewSet, Integer>> {
private final int mTaskId;
public GetPreviewSetListener(Context context, int stageId, String sceneTag, int taskId) {
super(context, stageId, sceneTag);
mTaskId = taskId;
}
@Override
public void onSuccess(Pair<PreviewSet, Integer> result) {
GalleryPreviewsScene scene = getScene();
if (scene != null) {
scene.onGetPreviewSetSuccess(result, mTaskId);
}
}
@Override
public void onFailure(Exception e) {
GalleryPreviewsScene scene = getScene();
if (scene != null) {
scene.onGetPreviewSetFailure(e, mTaskId);
}
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryPreviewsScene;
}
}
private static clreplaced GalleryPreviewHolder extends RecyclerView.ViewHolder {
public LoadImageView image;
public TextView text;
public GalleryPreviewHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.image);
text = itemView.findViewById(R.id.text);
}
}
private clreplaced GalleryPreviewAdapter extends RecyclerView.Adapter<GalleryPreviewHolder> {
private final LayoutInflater mInflater;
public GalleryPreviewAdapter() {
mInflater = getLayoutInflater2();
replacedertUtils.replacedertNotNull(mInflater);
}
@NonNull
@Override
public GalleryPreviewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new GalleryPreviewHolder(mInflater.inflate(R.layout.item_gallery_preview, parent, false));
}
@Override
@SuppressLint("SetTextI18n")
public void onBindViewHolder(@NonNull GalleryPreviewHolder holder, int position) {
if (null != mHelper) {
GalleryPreview preview = mHelper.getDataAtEx(position);
if (preview != null) {
preview.load(holder.image);
holder.text.setText(Integer.toString(preview.getPosition() + 1));
}
}
holder.itemView.setOnClickListener(v -> onItemClick(position));
}
@Override
public int gereplacedemCount() {
return mHelper != null ? mHelper.size() : 0;
}
}
private clreplaced GalleryPreviewHelper extends ContentLayout.ContentHelper<GalleryPreview> {
@Override
protected void getPageData(final int taskId, int type, int page) {
MainActivity activity = getActivity2();
if (null == activity || null == mClient || null == mGalleryInfo) {
onGetException(taskId, new EhException(getString(R.string.error_cannot_find_gallery)));
return;
}
String url = EhUrl.getGalleryDetailUrl(mGalleryInfo.gid, mGalleryInfo.token, page, false);
EhRequest request = new EhRequest();
request.setMethod(EhClient.METHOD_GET_PREVIEW_SET);
request.setCallback(new GetPreviewSetListener(getContext(), activity.getStageId(), getTag(), taskId));
request.setArgs(url);
mClient.execute(request);
}
@Override
protected Context getContext() {
return GalleryPreviewsScene.this.getContext2();
}
@Override
protected void notifyDataSetChanged() {
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
protected boolean isDuplicate(GalleryPreview d1, GalleryPreview d2) {
return false;
}
}
private clreplaced GoToDialogHelper implements View.OnClickListener, DialogInterface.OnDismissListener {
private final int mPages;
private final int mCurrentPage;
@Nullable
private Slider mSlider;
@Nullable
private Dialog mDialog;
private GoToDialogHelper(int pages, int currentPage) {
mPages = pages;
mCurrentPage = currentPage;
}
public void setDialog(@NonNull AlertDialog dialog) {
mDialog = dialog;
((TextView) ViewUtils.$$(dialog, R.id.start)).setText(String.format(Locale.US, "%d", 1));
((TextView) ViewUtils.$$(dialog, R.id.end)).setText(String.format(Locale.US, "%d", mPages));
mSlider = (Slider) ViewUtils.$$(dialog, R.id.slider);
mSlider.setRange(1, mPages);
mSlider.setProgress(mCurrentPage + 1);
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(this);
dialog.setOnDismissListener(this);
}
@Override
public void onClick(View v) {
if (null == mSlider) {
return;
}
int page = mSlider.getProgress() - 1;
if (page >= 0 && page < mPages && mHelper != null) {
mHelper.goTo(page);
if (mDialog != null) {
mDialog.dismiss();
mDialog = null;
}
} else {
showTip(R.string.error_out_of_range, LENGTH_LONG);
}
}
@Override
public void onDismiss(DialogInterface dialog) {
mDialog = null;
mSlider = null;
}
}
}
18
Source : HostsActivity.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
public clreplaced HostsActivity extends ToolbarActivity implements View.OnClickListener {
private static final String DIALOG_TAG_ADD_HOST = AddHostDialogFragment.clreplaced.getName();
private static final String DIALOG_TAG_EDIT_HOST = EditHostDialogFragment.clreplaced.getName();
private static final String KEY_HOST = "com.hippo.ehviewer.ui.HostsActivity.HOST";
private static final String KEY_IP = "com.hippo.ehviewer.ui.HostsActivity.IP";
private Hosts hosts;
private List<Pair<String, String>> data;
private EasyRecyclerView recyclerView;
private View tip;
private HostsAdapter adapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
hosts = EhApplication.getHosts(this);
data = hosts.getAll();
setContentView(R.layout.activity_hosts);
setreplacedle(R.string.hosts);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
recyclerView = findViewById(R.id.recycler_view);
tip = findViewById(R.id.tip);
FloatingActionButton fab = findViewById(R.id.fab);
adapter = new HostsAdapter();
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(this, R.attr.dividerColor), LayoutUtils.dp2pix(this, 1));
decoration.setShowLastDivider(true);
recyclerView.addItemDecoration(decoration);
// recyclerView.setSelector(Ripple.generateRippleDrawable(this, !AttrResources.getAttrBoolean(this, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
recyclerView.setHasFixedSize(true);
// recyclerView.setOnItemClickListener(this);
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(), recyclerView.getPaddingRight(), recyclerView.getPaddingBottom() + getResources().getDimensionPixelOffset(R.dimen.gallery_padding_bottom_fab));
fab.setOnClickListener(this);
recyclerView.setVisibility(data.isEmpty() ? View.GONE : View.VISIBLE);
tip.setVisibility(data.isEmpty() ? View.VISIBLE : View.GONE);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.gereplacedemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public boolean onItemClick(int position) {
Pair<String, String> pair = data.get(position);
Bundle args = new Bundle();
args.putString(KEY_HOST, pair.first);
args.putString(KEY_IP, pair.second);
DialogFragment fragment = new EditHostDialogFragment();
fragment.setArguments(args);
fragment.show(getSupportFragmentManager(), DIALOG_TAG_EDIT_HOST);
return true;
}
@Override
public void onClick(View v) {
new AddHostDialogFragment().show(getSupportFragmentManager(), DIALOG_TAG_ADD_HOST);
}
private void notifyHostsChanges() {
data = hosts.getAll();
recyclerView.setVisibility(data.isEmpty() ? View.GONE : View.VISIBLE);
tip.setVisibility(data.isEmpty() ? View.VISIBLE : View.GONE);
adapter.notifyDataSetChanged();
}
public abstract static clreplaced HostDialogFragment extends DialogFragment {
private TextView host;
private TextView ip;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_hosts, null, false);
host = view.findViewById(R.id.host);
ip = view.findViewById(R.id.ip);
Bundle arguments = getArguments();
if (savedInstanceState == null && arguments != null) {
host.setText(arguments.getString(KEY_HOST));
ip.setText(arguments.getString(KEY_IP));
}
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(requireContext()).setView(view);
onCreateDialogBuilder(builder);
AlertDialog dialog = builder.create();
dialog.setOnShowListener(d -> onCreateDialog((AlertDialog) d));
return dialog;
}
protected abstract void onCreateDialogBuilder(AlertDialog.Builder builder);
protected abstract void onCreateDialog(AlertDialog dialog);
protected void put(AlertDialog dialog) {
TextView host = dialog.findViewById(R.id.host);
TextView ip = dialog.findViewById(R.id.ip);
String hostString = host.getText().toString().trim().toLowerCase(Locale.US);
String ipString = ip.getText().toString().trim();
if (!Hosts.isValidHost(hostString)) {
TextInputLayout hostInputLayout = dialog.findViewById(R.id.host_input_layout);
hostInputLayout.setError(getContext().getString(R.string.invalid_host));
return;
}
if (!Hosts.isValidIp(ipString)) {
TextInputLayout ipInputLayout = dialog.findViewById(R.id.ip_input_layout);
ipInputLayout.setError(getContext().getString(R.string.invalid_ip));
return;
}
HostsActivity activity = (HostsActivity) dialog.getOwnerActivity();
activity.hosts.put(hostString, ipString);
activity.notifyHostsChanges();
dialog.dismiss();
}
protected void delete(AlertDialog dialog) {
TextView host = dialog.findViewById(R.id.host);
String hostString = host.getText().toString().trim().toLowerCase(Locale.US);
HostsActivity activity = (HostsActivity) dialog.getOwnerActivity();
activity.hosts.delete(hostString);
activity.notifyHostsChanges();
dialog.dismiss();
}
}
public static clreplaced AddHostDialogFragment extends HostDialogFragment {
@Override
protected void onCreateDialogBuilder(AlertDialog.Builder builder) {
builder.setreplacedle(R.string.add_host);
builder.setPositiveButton(R.string.add_host_add, null);
builder.setNegativeButton(android.R.string.cancel, null);
}
@Override
protected void onCreateDialog(AlertDialog dialog) {
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v -> put(dialog));
}
}
public static clreplaced EditHostDialogFragment extends HostDialogFragment {
@Override
protected void onCreateDialogBuilder(AlertDialog.Builder builder) {
builder.setreplacedle(R.string.edit_host);
builder.setPositiveButton(R.string.edit_host_confirm, null);
builder.setNegativeButton(R.string.edit_host_delete, null);
}
@Override
protected void onCreateDialog(AlertDialog dialog) {
dialog.findViewById(R.id.host_input_layout).setEnabled(false);
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v -> put(dialog));
dialog.getButton(DialogInterface.BUTTON_NEGATIVE).setOnClickListener(v -> delete(dialog));
}
}
private clreplaced HostsHolder extends RecyclerView.ViewHolder {
public final TextView host;
public final TextView ip;
public HostsHolder(View itemView) {
super(itemView);
host = itemView.findViewById(R.id.host);
ip = itemView.findViewById(R.id.ip);
}
}
private clreplaced HostsAdapter extends RecyclerView.Adapter<HostsHolder> {
private final LayoutInflater inflater = getLayoutInflater();
@NonNull
@Override
public HostsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new HostsHolder(inflater.inflate(R.layout.item_hosts, parent, false));
}
@Override
public void onBindViewHolder(@NonNull HostsHolder holder, int position) {
Pair<String, String> pair = data.get(position);
holder.host.setText(pair.first);
holder.ip.setText(pair.second);
holder.itemView.setOnClickListener(v -> onItemClick(position));
}
@Override
public int gereplacedemCount() {
return data.size();
}
}
}
18
Source : FilterActivity.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
public clreplaced FilterActivity extends ToolbarActivity {
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private ViewTransition mViewTransition;
@Nullable
private FilterAdapter mAdapter;
@Nullable
private FilterList mFilterList;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_filter);
setreplacedle(R.string.filter);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
mFilterList = new FilterList();
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(this, R.id.recycler_view);
TextView tip = (TextView) ViewUtils.$$(this, R.id.tip);
mViewTransition = new ViewTransition(mRecyclerView, tip);
Drawable drawable = DrawableManager.getVectorDrawable(this, R.drawable.big_filter);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
mAdapter = new FilterAdapter();
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setClipToPadding(false);
mRecyclerView.setClipChildren(false);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.hasFixedSize();
mRecyclerView.sereplacedemAnimator(null);
updateView(false);
}
private void updateView(boolean animation) {
if (null == mViewTransition) {
return;
}
if (null == mFilterList || 0 == mFilterList.size()) {
mViewTransition.showView(1, animation);
} else {
mViewTransition.showView(0, animation);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mRecyclerView = null;
mViewTransition = null;
mAdapter = null;
mFilterList = null;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.activity_filter, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.gereplacedemId()) {
case android.R.id.home:
finish();
return true;
case R.id.action_add:
showAddFilterDialog();
return true;
case R.id.action_tip:
showTipDialog();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void showTipDialog() {
new MaterialAlertDialogBuilder(this).setreplacedle(R.string.filter).setMessage(R.string.filter_tip).show();
}
private void showAddFilterDialog() {
AlertDialog dialog = new MaterialAlertDialogBuilder(this).setreplacedle(R.string.add_filter).setView(R.layout.dialog_add_filter).setPositiveButton(R.string.add, null).setNegativeButton(android.R.string.cancel, null).show();
AddFilterDialogHelper helper = new AddFilterDialogHelper();
helper.setDialog(dialog);
}
private void showDeleteFilterDialog(final Filter filter) {
String message = getString(R.string.delete_filter, filter.text);
new MaterialAlertDialogBuilder(this).setMessage(message).setPositiveButton(R.string.delete, (dialog, which) -> {
if (DialogInterface.BUTTON_POSITIVE != which || null == mFilterList) {
return;
}
mFilterList.delete(filter);
if (null != mAdapter) {
mAdapter.notifyDataSetChanged();
}
updateView(true);
}).setNegativeButton(android.R.string.cancel, null).show();
}
private clreplaced AddFilterDialogHelper implements View.OnClickListener {
@Nullable
private AlertDialog mDialog;
@Nullable
private Spinner mSpinner;
@Nullable
private TextInputLayout mInputLayout;
@Nullable
private EditText mEditText;
public void setDialog(AlertDialog dialog) {
mDialog = dialog;
mSpinner = (Spinner) ViewUtils.$$(dialog, R.id.spinner);
mInputLayout = (TextInputLayout) ViewUtils.$$(dialog, R.id.text_input_layout);
mEditText = mInputLayout.getEditText();
View button = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (null != button) {
button.setOnClickListener(this);
}
}
@Override
public void onClick(View v) {
if (null == mFilterList || null == mDialog || null == mSpinner || null == mInputLayout || null == mEditText) {
return;
}
String text = mEditText.getText().toString().trim();
if (TextUtils.isEmpty(text)) {
mInputLayout.setError(getString(R.string.text_is_empty));
return;
} else {
mInputLayout.setError(null);
}
int mode = mSpinner.getSelectedItemPosition();
Filter filter = new Filter();
filter.mode = mode;
filter.text = text;
mFilterList.add(filter);
if (null != mAdapter) {
mAdapter.notifyDataSetChanged();
}
updateView(true);
mDialog.dismiss();
mDialog = null;
mSpinner = null;
mInputLayout = null;
mEditText = null;
}
}
private clreplaced FilterHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final TextView text;
private final ImageView icon;
public FilterHolder(View itemView) {
super(itemView);
text = (TextView) ViewUtils.$$(itemView, R.id.text);
icon = itemView.findViewById(R.id.icon);
if (null != icon) {
icon.setOnClickListener(this);
}
// click on the filter text to enable/disable it
text.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int position = getAdapterPosition();
if (position < 0 || null == mFilterList) {
return;
}
Filter filter = mFilterList.get(position);
if (FilterList.MODE_HEADER != filter.mode) {
if (v instanceof ImageView) {
showDeleteFilterDialog(filter);
} else if (v instanceof TextView) {
mFilterList.trigger(filter);
// for updating delete line on filter text
mAdapter.notifyItemChanged(getAdapterPosition());
}
}
}
}
private clreplaced FilterAdapter extends RecyclerView.Adapter<FilterHolder> {
private static final int TYPE_ITEM = 0;
private static final int TYPE_HEADER = 1;
@Override
public int gereplacedemViewType(int position) {
if (null == mFilterList) {
return TYPE_ITEM;
}
if (mFilterList.get(position).mode == FilterList.MODE_HEADER) {
return TYPE_HEADER;
} else {
return TYPE_ITEM;
}
}
@Override
public FilterHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layoutId;
switch(viewType) {
default:
case TYPE_ITEM:
layoutId = R.layout.item_filter;
break;
case TYPE_HEADER:
layoutId = R.layout.item_filter_header;
break;
}
FilterHolder holder = new FilterHolder(getLayoutInflater().inflate(layoutId, parent, false));
if (R.layout.item_filter == layoutId) {
holder.icon.setImageDrawable(DrawableManager.getVectorDrawable(FilterActivity.this, R.drawable.v_delete_x24));
}
return holder;
}
@Override
public void onBindViewHolder(FilterHolder holder, int position) {
if (null == mFilterList) {
return;
}
Filter filter = mFilterList.get(position);
if (FilterList.MODE_HEADER == filter.mode) {
holder.text.setText(filter.text);
} else {
holder.text.setText(filter.text);
// add a delete line if the filter is disabled
if (!filter.enable) {
holder.text.setPaintFlags(holder.text.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
} else {
holder.text.setPaintFlags(holder.text.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
}
}
}
@Override
public int gereplacedemCount() {
return null != mFilterList ? mFilterList.size() : 0;
}
}
private clreplaced FilterList {
public static final int MODE_HEADER = -1;
private final EhFilter mEhFilter;
private final List<Filter> mreplacedleFilterList;
private final List<Filter> mUploaderFilterList;
private final List<Filter> mTagFilterList;
private final List<Filter> mTagNamespaceFilterList;
private Filter mreplacedleHeader;
private Filter mUploaderHeader;
private Filter mTagHeader;
private Filter mTagNamespaceHeader;
public FilterList() {
mEhFilter = EhFilter.getInstance();
mreplacedleFilterList = mEhFilter.getreplacedleFilterList();
mUploaderFilterList = mEhFilter.getUploaderFilterList();
mTagFilterList = mEhFilter.getTagFilterList();
mTagNamespaceFilterList = mEhFilter.getTagNamespaceFilterList();
}
public int size() {
int count = 0;
int size = mreplacedleFilterList.size();
count += 0 == size ? 0 : size + 1;
size = mUploaderFilterList.size();
count += 0 == size ? 0 : size + 1;
size = mTagFilterList.size();
count += 0 == size ? 0 : size + 1;
size = mTagNamespaceFilterList.size();
count += 0 == size ? 0 : size + 1;
return count;
}
private Filter getreplacedleHeader() {
if (null == mreplacedleHeader) {
mreplacedleHeader = new Filter();
mreplacedleHeader.mode = MODE_HEADER;
mreplacedleHeader.text = getString(R.string.filter_replacedle);
}
return mreplacedleHeader;
}
private Filter getUploaderHeader() {
if (null == mUploaderHeader) {
mUploaderHeader = new Filter();
mUploaderHeader.mode = MODE_HEADER;
mUploaderHeader.text = getString(R.string.filter_uploader);
}
return mUploaderHeader;
}
private Filter getTagHeader() {
if (null == mTagHeader) {
mTagHeader = new Filter();
mTagHeader.mode = MODE_HEADER;
mTagHeader.text = getString(R.string.filter_tag);
}
return mTagHeader;
}
private Filter getTagNamespaceHeader() {
if (null == mTagNamespaceHeader) {
mTagNamespaceHeader = new Filter();
mTagNamespaceHeader.mode = MODE_HEADER;
mTagNamespaceHeader.text = getString(R.string.filter_tag_namespace);
}
return mTagNamespaceHeader;
}
public Filter get(int index) {
int size = mreplacedleFilterList.size();
if (0 != size) {
if (index == 0) {
return getreplacedleHeader();
} else if (index <= size) {
return mreplacedleFilterList.get(index - 1);
} else {
index -= size + 1;
}
}
size = mUploaderFilterList.size();
if (0 != size) {
if (index == 0) {
return getUploaderHeader();
} else if (index <= size) {
return mUploaderFilterList.get(index - 1);
} else {
index -= size + 1;
}
}
size = mTagFilterList.size();
if (0 != size) {
if (index == 0) {
return getTagHeader();
} else if (index <= size) {
return mTagFilterList.get(index - 1);
} else {
index -= size + 1;
}
}
size = mTagNamespaceFilterList.size();
if (0 != size) {
if (index == 0) {
return getTagNamespaceHeader();
} else if (index <= size) {
return mTagNamespaceFilterList.get(index - 1);
} else {
index -= size + 1;
}
}
throw new IndexOutOfBoundsException();
}
public void add(Filter filter) {
mEhFilter.addFilter(filter);
}
public void delete(Filter filter) {
mEhFilter.deleteFilter(filter);
}
public void trigger(Filter filter) {
mEhFilter.triggerFilter(filter);
}
}
}
18
Source : ContentLayout.java
with Apache License 2.0
from axlecho
with Apache License 2.0
from axlecho
public clreplaced ContentLayout extends FrameLayout {
private ProgressView mProgressView;
private TextView mTipView;
private ViewGroup mContentView;
private RefreshLayout mRefreshLayout;
private EasyRecyclerView mRecyclerView;
private FastScroller mFastScroller;
private ContentHelper mContentHelper;
private int mRecyclerViewOriginTop;
private int mRecyclerViewOriginBottom;
public ContentLayout(Context context) {
super(context);
init(context);
}
public ContentLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ContentLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
LayoutInflater.from(context).inflate(R.layout.widget_content_layout, this);
mProgressView = (ProgressView) findViewById(R.id.progress);
mTipView = (TextView) findViewById(R.id.tip);
mContentView = (ViewGroup) findViewById(R.id.content_view);
mRefreshLayout = (RefreshLayout) mContentView.findViewById(R.id.refresh_layout);
mFastScroller = (FastScroller) mContentView.findViewById(R.id.fast_scroller);
mRecyclerView = (EasyRecyclerView) mRefreshLayout.findViewById(R.id.recycler_view);
mFastScroller.attachToRecyclerView(mRecyclerView);
HandlerDrawable drawable = new HandlerDrawable();
drawable.setColor(AttrResources.getAttrColor(context, R.attr.widgetColorThemeAccent));
mFastScroller.setHandlerDrawable(drawable);
mRefreshLayout.setHeaderColorSchemeResources(R.color.loading_indicator_red, R.color.loading_indicator_purple, R.color.loading_indicator_blue, R.color.loading_indicator_cyan, R.color.loading_indicator_green, R.color.loading_indicator_yellow);
mRefreshLayout.setFooterColorSchemeResources(R.color.loading_indicator_red, R.color.loading_indicator_blue, R.color.loading_indicator_green, R.color.loading_indicator_orange);
mRecyclerViewOriginTop = mRecyclerView.getPaddingTop();
mRecyclerViewOriginBottom = mRecyclerView.getPaddingBottom();
}
@NonNull
public EasyRecyclerView getRecyclerView() {
return mRecyclerView;
}
public FastScroller getFastScroller() {
return mFastScroller;
}
public RefreshLayout getRefreshLayout() {
return mRefreshLayout;
}
public void setHelper(ContentHelper helper) {
mContentHelper = helper;
helper.init(this);
}
public void showFastScroll() {
if (!mFastScroller.isAttached()) {
mFastScroller.attachToRecyclerView(mRecyclerView);
}
}
public void hideFastScroll() {
mFastScroller.detachedFromRecyclerView();
}
public void setFitPaddingTop(int fitPaddingTop) {
// RecyclerView
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerViewOriginTop + fitPaddingTop, mRecyclerView.getPaddingRight(), mRecyclerView.getPaddingBottom());
// RefreshLayout
// TODO
mRefreshLayout.setProgressViewOffset(false, fitPaddingTop, fitPaddingTop + LayoutUtils.dp2pix(getContext(), 32));
}
public void setFitPaddingBottom(int fitPaddingBottom) {
// RecyclerView
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), mRecyclerViewOriginBottom + fitPaddingBottom);
}
@Override
protected Parcelable onSaveInstanceState() {
return mContentHelper.saveInstanceState(super.onSaveInstanceState());
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(mContentHelper.restoreInstanceState(state));
}
public abstract static clreplaced ContentHelper<E extends Parcelable> implements ViewTransition.OnShowViewListener {
private static final String TAG = ContentHelper.clreplaced.getSimpleName();
private static final int CHECK_DUPLICATE_RANGE = 50;
private static final String KEY_SUPER = "super";
private static final String KEY_SHOWN_VIEW = "shown_view";
private static final String KEY_TIP = "tip";
private static final String KEY_DATA = "data";
private static final String KEY_NEXT_ID = "next_id";
private static final String KEY_PAGE_DIVIDER = "page_divider";
private static final String KEY_START_PAGE = "start_page";
private static final String KEY_END_PAGE = "end_page";
private static final String KEY_PAGES = "pages";
public static final int TYPE_REFRESH = 0;
public static final int TYPE_PRE_PAGE = 1;
public static final int TYPE_PRE_PAGE_KEEP_POS = 2;
public static final int TYPE_NEXT_PAGE = 3;
public static final int TYPE_NEXT_PAGE_KEEP_POS = 4;
public static final int TYPE_SOMEWHERE = 5;
public static final int TYPE_REFRESH_PAGE = 6;
public static final int REFRESH_TYPE_HEADER = 0;
public static final int REFRESH_TYPE_FOOTER = 1;
public static final int REFRESH_TYPE_PROGRESS_VIEW = 2;
private ProgressView mProgressView;
private TextView mTipView;
private ViewGroup mContentView;
private RefreshLayout mRefreshLayout;
private EasyRecyclerView mRecyclerView;
private ViewTransition mViewTransition;
private OnClickListener refreshListener = v -> refresh();
private OnClickListener loginListener = new OnClickListener() {
@Override
public void onClick(View v) {
// login
Announcer announcer = new Announcer(SignInScene.clreplaced);
startScene(announcer);
mTipView.setOnClickListener(refreshListener);
}
};
public void startScene(Announcer announcer) {
Context activity = getContext();
if (activity instanceof StageActivity) {
((StageActivity) activity).startScene(announcer);
}
}
/**
* Store data
*/
private ArrayList<E> mData = new ArrayList<>();
/**
* Generate task id
*/
private final IntIdGenerator mIdGenerator = new IntIdGenerator();
/**
* Store the page divider index
* <p>
* For example, the data contain page 3, page 4, page 5,
* page 3 size is 7, page 4 size is 8, page 5 size is 9,
* so <code>mPageDivider</code> contain 7, 15, 24.
*/
private IntList mPageDivider = new IntList();
/**
* The first page in <code>mData</code>
*/
private int mStartPage;
/**
* The last page + 1 in <code>mData</code>
*/
private int mEndPage;
/**
* The available page count.
*/
private int mPages;
private int mNextPage;
private int mCurrentTaskId;
private int mCurrentTaskType;
private int mCurrentTaskPage;
private int mNextPageScrollSize;
private String mEmptyString = "No hint";
private final RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (!mRefreshLayout.isRefreshing() && mRefreshLayout.isAlmostBottom() && mEndPage < mPages) {
// Get next page
mRefreshLayout.setFooterRefreshing(true);
mOnRefreshListener.onFooterRefresh();
}
}
};
private final RefreshLayout.OnRefreshListener mOnRefreshListener = new RefreshLayout.OnRefreshListener() {
@Override
public void onHeaderRefresh() {
if (mStartPage > 0) {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_PRE_PAGE_KEEP_POS;
mCurrentTaskPage = mStartPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
doRefresh();
}
}
@Override
public void onFooterRefresh() {
if (mEndPage < mPages) {
// Get next page
// Fill pages before NextPage with empty list
while (mNextPage > mEndPage && mEndPage < mPages) {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
onGetPageData(mCurrentTaskId, mPages, mNextPage, Collections.emptyList());
}
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else if (mEndPage == mPages) {
// Refresh last page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_REFRESH_PAGE;
mCurrentTaskPage = mEndPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
Log.e(TAG, "Try to footer refresh, but mEndPage = " + mEndPage + ", mPages = " + mPages);
mRefreshLayout.setFooterRefreshing(false);
}
}
};
private final LayoutManagerUtils.OnScrollToPositionListener mOnScrollToPositionListener = new LayoutManagerUtils.OnScrollToPositionListener() {
@Override
public void onScrollToPosition(int position) {
ContentHelper.this.onScrollToPosition(position);
}
};
private void init(ContentLayout contentLayout) {
mNextPageScrollSize = LayoutUtils.dp2pix(contentLayout.getContext(), 48);
mProgressView = contentLayout.mProgressView;
mTipView = contentLayout.mTipView;
mContentView = contentLayout.mContentView;
mRefreshLayout = contentLayout.mRefreshLayout;
mRecyclerView = contentLayout.mRecyclerView;
Drawable drawable = DrawableManager.getVectorDrawable(getContext(), R.drawable.big_sad_pandroid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
mTipView.setCompoundDrawables(null, drawable, null, null);
mViewTransition = new ViewTransition(mContentView, mProgressView, mTipView);
mViewTransition.setOnShowViewListener(this);
mRecyclerView.addOnScrollListener(mOnScrollListener);
mRefreshLayout.setOnRefreshListener(mOnRefreshListener);
mTipView.setOnClickListener(refreshListener);
}
/**
* Call {@link #onGetPageData(int, int, int, List)} when get data
*
* @param taskId task id
* @param page the page to get
*/
protected abstract void getPageData(int taskId, int type, int page);
protected abstract Context getContext();
protected abstract void notifyDataSetChanged();
protected abstract void notifyItemRangeRemoved(int positionStart, int itemCount);
protected abstract void notifyItemRangeInserted(int positionStart, int itemCount);
protected void onScrollToPosition(int postion) {
}
@Override
public void onShowView(View hiddenView, View shownView) {
}
public int getShownViewIndex() {
return mViewTransition.getShownViewIndex();
}
public void setRefreshLayoutEnable(boolean enable) {
mRefreshLayout.setEnabled(enable);
}
public void setEnable(boolean enable) {
mRefreshLayout.setEnabled(enable);
}
public void setEmptyString(String str) {
mEmptyString = str;
}
public List<E> getData() {
return mData;
}
/**
* @throws IndexOutOfBoundsException if {@code location < 0 || location >= size()}
*/
public E getDataAt(int location) {
return mData.get(location);
}
@Nullable
public E getDataAtEx(int location) {
if (location >= 0 && location < mData.size()) {
return mData.get(location);
} else {
return null;
}
}
public int size() {
return mData.size();
}
public boolean isCurrentTask(int taskId) {
return mCurrentTaskId == taskId;
}
public int getPages() {
return mPages;
}
public void addAt(int index, E data) {
mData.add(index, data);
onAddData(data);
for (int i = 0, n = mPageDivider.size(); i < n; i++) {
int divider = mPageDivider.get(i);
if (index < divider) {
mPageDivider.set(i, divider + 1);
}
}
notifyItemRangeInserted(index, 1);
}
public void removeAt(int index) {
E data = mData.remove(index);
onRemoveData(data);
for (int i = 0, n = mPageDivider.size(); i < n; i++) {
int divider = mPageDivider.get(i);
if (index < divider) {
mPageDivider.set(i, divider - 1);
}
}
notifyItemRangeRemoved(index, 1);
}
protected abstract boolean isDuplicate(E d1, E d2);
private void removeDuplicateData(List<E> data, int start, int end) {
start = Math.max(0, start);
end = Math.min(mData.size(), end);
for (Iterator<E> iterator = data.iterator(); iterator.hasNext(); ) {
E d = iterator.next();
for (int i = start; i < end; i++) {
if (isDuplicate(d, mData.get(i))) {
iterator.remove();
break;
}
}
}
}
protected void onAddData(E data) {
}
protected void onAddData(List<E> data) {
}
protected void onRemoveData(E data) {
}
protected void onRemoveData(List<E> data) {
}
protected void onClearData() {
}
public void onGetPageData(int taskId, int pages, int nextPage, List<E> data) {
if (mCurrentTaskId == taskId) {
int dataSize;
switch(mCurrentTaskType) {
case TYPE_REFRESH:
mStartPage = 0;
mEndPage = 1;
mPages = pages;
mNextPage = nextPage;
mPageDivider.clear();
mPageDivider.add(data.size());
if (data.isEmpty()) {
mData.clear();
onClearData();
notifyDataSetChanged();
if (true || mEndPage >= mPages) {
// Not found
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showProgressBar();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.clear();
onClearData();
mData.addAll(data);
onAddData(data);
notifyDataSetChanged();
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
// RecyclerView scroll
if (mRecyclerView.isAttachedToWindow()) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
break;
case TYPE_PRE_PAGE:
case TYPE_PRE_PAGE_KEEP_POS:
removeDuplicateData(data, 0, CHECK_DUPLICATE_RANGE);
dataSize = data.size();
for (int i = 0, n = mPageDivider.size(); i < n; i++) {
mPageDivider.set(i, mPageDivider.get(i) + dataSize);
}
mPageDivider.add(0, dataSize);
mStartPage--;
mPages = Math.max(mEndPage, pages);
// replacedert mStartPage >= 0
if (data.isEmpty()) {
if (true || mStartPage <= 0) {
// OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mCurrentTaskType == TYPE_PRE_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll, to top
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
} else {
// Keep UI
// Get previous
mCurrentTaskId = mIdGenerator.nextId();
// Keep mCurrentTaskType
mCurrentTaskPage = mStartPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.addAll(0, data);
onAddData(data);
notifyItemRangeInserted(0, data.size());
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
if (mCurrentTaskType == TYPE_PRE_PAGE_KEEP_POS) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionProperly(mRecyclerView.getLayoutManager(), getContext(), dataSize - 1, mOnScrollToPositionListener);
} else {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
}
break;
case TYPE_NEXT_PAGE:
case TYPE_NEXT_PAGE_KEEP_POS:
removeDuplicateData(data, mData.size() - CHECK_DUPLICATE_RANGE, mData.size());
dataSize = data.size();
int oldDataSize = mData.size();
mPageDivider.add(oldDataSize + dataSize);
mEndPage++;
mNextPage = nextPage;
mPages = Math.max(mEndPage, pages);
if (data.isEmpty()) {
if (true || mEndPage >= mPages) {
// OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mCurrentTaskType == TYPE_NEXT_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), oldDataSize, 0);
onScrollToPosition(oldDataSize);
}
}
} else {
// Keep UI
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
// Keep mCurrentTaskType
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.addAll(data);
onAddData(data);
notifyItemRangeInserted(oldDataSize, dataSize);
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mRecyclerView.isAttachedToWindow()) {
if (mCurrentTaskType == TYPE_NEXT_PAGE_KEEP_POS) {
mRecyclerView.stopScroll();
mRecyclerView.smoothScrollBy(0, mNextPageScrollSize);
} else {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), oldDataSize, 0);
onScrollToPosition(oldDataSize);
}
}
}
break;
case TYPE_SOMEWHERE:
mStartPage = mCurrentTaskPage;
mEndPage = mCurrentTaskPage + 1;
mNextPage = nextPage;
mPages = pages;
mPageDivider.clear();
mPageDivider.add(data.size());
if (data.isEmpty()) {
mData.clear();
onClearData();
notifyDataSetChanged();
if (true || mEndPage >= mPages) {
// Not found
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showProgressBar();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.clear();
onClearData();
mData.addAll(data);
onAddData(data);
notifyDataSetChanged();
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
if (mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
break;
case TYPE_REFRESH_PAGE:
if (mCurrentTaskPage < mStartPage || mCurrentTaskPage >= mEndPage) {
Log.e(TAG, "TYPE_REFRESH_PAGE, but mCurrentTaskPage = " + mCurrentTaskPage + ", mStartPage = " + mStartPage + ", mEndPage = " + mEndPage);
break;
}
if (mCurrentTaskPage == mEndPage - 1) {
mNextPage = nextPage;
}
mPages = Math.max(mEndPage, pages);
int oldIndexStart = mCurrentTaskPage == mStartPage ? 0 : mPageDivider.get(mCurrentTaskPage - mStartPage - 1);
int oldIndexEnd = mPageDivider.get(mCurrentTaskPage - mStartPage);
List<E> toRemove = mData.subList(oldIndexStart, oldIndexEnd);
onRemoveData(toRemove);
toRemove.clear();
removeDuplicateData(data, oldIndexStart - CHECK_DUPLICATE_RANGE, oldIndexStart + CHECK_DUPLICATE_RANGE);
int newIndexStart = oldIndexStart;
int newIndexEnd = newIndexStart + data.size();
mData.addAll(oldIndexStart, data);
onAddData(data);
notifyDataSetChanged();
for (int i = mCurrentTaskPage - mStartPage, n = mPageDivider.size(); i < n; i++) {
mPageDivider.set(i, mPageDivider.get(i) - oldIndexEnd + newIndexEnd);
}
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
showContent();
// RecyclerView scroll
if (newIndexEnd > oldIndexEnd && newIndexEnd > 0 && mRecyclerView.isAttachedToWindow()) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), newIndexEnd - 1, 0);
onScrollToPosition(newIndexEnd - 1);
}
}
break;
}
}
}
public void onGetException(int taskId, Exception e) {
if (mCurrentTaskId == taskId) {
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
String readableError;
if (e != null) {
e.printStackTrace();
if (e instanceof HttpException && ((HttpException) e).code() == 401) {
// do login
mTipView.setOnClickListener(loginListener);
}
readableError = ExceptionUtils.getReadableString(e);
} else {
readableError = getContext().getString(R.string.error_unknown);
}
if (mViewTransition.getShownViewIndex() == 0) {
Toast.makeText(getContext(), readableError, Toast.LENGTH_SHORT).show();
} else {
showText(readableError);
}
}
}
public void showContent() {
mViewTransition.showView(0);
}
private boolean isContentShowing() {
return mViewTransition.getShownViewIndex() == 0;
}
public void showProgressBar() {
showProgressBar(true);
}
public void showProgressBar(boolean animation) {
mViewTransition.showView(1, animation);
}
public void showText(CharSequence text) {
mTipView.setText(text);
mViewTransition.showView(2);
}
public void showEmptyString() {
showText(mEmptyString);
}
/**
* Be carefull
*/
public void doGetData(int type, int page, int refreshType) {
switch(refreshType) {
default:
case REFRESH_TYPE_HEADER:
showContent();
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
break;
case REFRESH_TYPE_FOOTER:
showContent();
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(true);
break;
case REFRESH_TYPE_PROGRESS_VIEW:
showProgressBar();
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
break;
}
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = type;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
private void doRefresh() {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_REFRESH;
mCurrentTaskPage = 0;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
/**
* Lisk {@link #refresh()}, but no animation when show progress bar
*/
public void firstRefresh() {
showProgressBar(false);
doRefresh();
}
/**
* Show progress bar first, than do refresh
*/
public void refresh() {
showProgressBar();
doRefresh();
}
private void cancelCurrentTask() {
mCurrentTaskId = mIdGenerator.nextId();
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
}
private int getPageStart(int page) {
if (mStartPage == page) {
return 0;
} else {
return mPageDivider.get(page - mStartPage - 1);
}
}
private int getPageEnd(int page) {
return mPageDivider.get(page - mStartPage);
}
private int getPageForPosition(int position) {
if (position < 0) {
return -1;
}
IntList pageDivider = mPageDivider;
for (int i = 0, n = pageDivider.size(); i < n; i++) {
if (position < pageDivider.get(i)) {
return i + mStartPage;
}
}
return -1;
}
public int getPageForTop() {
return getPageForPosition(LayoutManagerUtils.getFirstVisibleItemPosition(mRecyclerView.getLayoutManager()));
}
public int getPageForBottom() {
return getPageForPosition(LayoutManagerUtils.getLastVisibleItemPosition(mRecyclerView.getLayoutManager()));
}
public boolean canGoTo() {
return isContentShowing();
}
/**
* Check range first!
*
* @param page the target page
* @throws IndexOutOfBoundsException
*/
public void goTo(int page) throws IndexOutOfBoundsException {
if (page < 0 || page >= mPages) {
throw new IndexOutOfBoundsException("Page count is " + mPages + ", page is " + page);
} else if (page >= mStartPage && page < mEndPage) {
cancelCurrentTask();
int position = getPageStart(page);
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), position, 0);
onScrollToPosition(position);
} else if (page == mStartPage - 1) {
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_PRE_PAGE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else if (page == mEndPage) {
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(true);
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
mRefreshLayout.setFooterRefreshing(false);
mRefreshLayout.setHeaderRefreshing(true);
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_SOMEWHERE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
}
private int mSavedDataId = IntIdGenerator.INVALID_ID;
protected Parcelable saveInstanceState(Parcelable superState) {
Bundle bundle = new Bundle();
bundle.putParcelable(KEY_SUPER, superState);
int shownView = mViewTransition.getShownViewIndex();
bundle.putInt(KEY_SHOWN_VIEW, shownView);
bundle.putString(KEY_TIP, mTipView.getText().toString());
// TODO It's a bad design
EhApplication app = (EhApplication) getContext().getApplicationContext();
if (mSavedDataId != IntIdGenerator.INVALID_ID) {
app.removeGlobalStuff(mSavedDataId);
mSavedDataId = IntIdGenerator.INVALID_ID;
}
mSavedDataId = app.putGlobalStuff(mData);
bundle.putInt(KEY_DATA, mSavedDataId);
bundle.putInt(KEY_NEXT_ID, mIdGenerator.nextId());
bundle.putParcelable(KEY_PAGE_DIVIDER, mPageDivider);
bundle.putInt(KEY_START_PAGE, mStartPage);
bundle.putInt(KEY_END_PAGE, mEndPage);
bundle.putInt(KEY_PAGES, mPages);
return bundle;
}
protected Parcelable restoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
mViewTransition.showView(bundle.getInt(KEY_SHOWN_VIEW), false);
mTipView.setText(bundle.getString(KEY_TIP));
mSavedDataId = bundle.getInt(KEY_DATA);
ArrayList<E> newData = null;
EhApplication app = (EhApplication) getContext().getApplicationContext();
if (mSavedDataId != IntIdGenerator.INVALID_ID) {
newData = (ArrayList<E>) app.removeGlobalStuff(mSavedDataId);
mSavedDataId = IntIdGenerator.INVALID_ID;
if (newData != null) {
mData = newData;
}
}
mIdGenerator.setNextId(bundle.getInt(KEY_NEXT_ID));
mPageDivider = bundle.getParcelable(KEY_PAGE_DIVIDER);
mStartPage = bundle.getInt(KEY_START_PAGE);
mEndPage = bundle.getInt(KEY_END_PAGE);
mPages = bundle.getInt(KEY_PAGES);
notifyDataSetChanged();
if (newData == null) {
mPageDivider.clear();
mStartPage = 0;
mEndPage = 0;
mPages = 0;
firstRefresh();
}
return bundle.getParcelable(KEY_SUPER);
} else {
return state;
}
}
}
}
18
Source : HistoryScene.java
with Apache License 2.0
from axlecho
with Apache License 2.0
from axlecho
public clreplaced HistoryScene extends ToolbarScene implements EasyRecyclerView.OnItemClickListener, EasyRecyclerView.OnItemLongClickListener {
/*---------------
View life cycle
---------------*/
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private ViewTransition mViewTransition;
@Nullable
private RecyclerView.Adapter<?> mAdapter;
@Nullable
private LazyList<HistoryInfo> mLazyList;
@Override
public int getNavCheckedItem() {
return R.id.nav_history;
}
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_history, container, false);
View content = ViewUtils.$$(view, R.id.content);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(content, R.id.recycler_view);
FastScroller fastScroller = (FastScroller) ViewUtils.$$(content, R.id.fast_scroller);
TextView tip = (TextView) ViewUtils.$$(view, R.id.tip);
mViewTransition = new ViewTransition(content, tip);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
Resources resources = context.getResources();
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_history);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
RecyclerViewTouchActionGuardManager guardManager = new RecyclerViewTouchActionGuardManager();
guardManager.setInterceptVerticalScrollingWhileAnimationRunning(true);
guardManager.setEnabled(true);
RecyclerViewSwipeManager swipeManager = new RecyclerViewSwipeManager();
mAdapter = new HistoryAdapter();
mAdapter.setHreplacedtableIds(true);
mAdapter = swipeManager.createWrappedAdapter(mAdapter);
mRecyclerView.setAdapter(mAdapter);
final GeneralItemAnimator animator = new SwipeDismissItemAnimator();
animator.setSupportsChangeAnimations(false);
mRecyclerView.sereplacedemAnimator(animator);
AutoStaggeredGridLayoutManager layoutManager = new AutoStaggeredGridLayoutManager(0, StaggeredGridLayoutManager.VERTICAL);
layoutManager.setColumnSize(resources.getDimensionPixelOffset(Settings.getDetailSizeResId()));
layoutManager.setStrategy(AutoStaggeredGridLayoutManager.STRATEGY_MIN_SIZE);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
mRecyclerView.setDrawSelectorOnTop(true);
mRecyclerView.setClipToPadding(false);
mRecyclerView.setOnItemClickListener(this);
mRecyclerView.setOnItemLongClickListener(this);
int interval = resources.getDimensionPixelOffset(R.dimen.gallery_list_interval);
int paddingH = resources.getDimensionPixelOffset(R.dimen.gallery_list_margin_h);
int paddingV = resources.getDimensionPixelOffset(R.dimen.gallery_list_margin_v);
MarginItemDecoration decoration = new MarginItemDecoration(interval, paddingH, paddingV, paddingH, paddingV);
mRecyclerView.addItemDecoration(decoration);
decoration.applyPaddings(mRecyclerView);
guardManager.attachRecyclerView(mRecyclerView);
swipeManager.attachRecyclerView(mRecyclerView);
fastScroller.attachToRecyclerView(mRecyclerView);
HandlerDrawable handlerDrawable = new HandlerDrawable();
handlerDrawable.setColor(AttrResources.getAttrColor(context, R.attr.widgetColorThemeAccent));
fastScroller.setHandlerDrawable(handlerDrawable);
updateLazyList();
updateView(false);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.history);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mLazyList) {
mLazyList.close();
mLazyList = null;
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
}
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
mViewTransition = null;
mAdapter = null;
}
// Remember to notify
private void updateLazyList() {
LazyList<HistoryInfo> lazyList = EhDB.getHistoryLazyList();
if (mLazyList != null) {
mLazyList.close();
}
mLazyList = lazyList;
}
private void updateView(boolean animation) {
if (null == mAdapter || null == mViewTransition) {
return;
}
if (mAdapter.gereplacedemCount() == 0) {
mViewTransition.showView(1, animation);
} else {
mViewTransition.showView(0, animation);
}
}
@Override
public void onNavigationClick() {
onBackPressed();
}
@Override
public int getMenuResId() {
return R.menu.scene_history;
}
private void showClearAllDialog() {
new AlertDialog.Builder(getContext2()).setMessage(R.string.clear_all_history).setPositiveButton(R.string.clear_all, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (DialogInterface.BUTTON_POSITIVE != which || null == mAdapter) {
return;
}
EhDB.clearHistoryInfo();
updateLazyList();
mAdapter.notifyDataSetChanged();
updateView(true);
}
}).show();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
// Skip when in choice mode
Context context = getContext2();
if (null == context) {
return false;
}
int id = item.gereplacedemId();
switch(id) {
case R.id.action_clear_all:
{
showClearAllDialog();
return true;
}
}
return false;
}
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
if (null == mLazyList) {
return false;
}
Bundle args = new Bundle();
args.putString(GalleryDetailScene.KEY_ACTION, GalleryDetailScene.ACTION_GALLERY_INFO);
args.putParcelable(GalleryDetailScene.KEY_GALLERY_INFO, new GalleryInfo(mLazyList.get(position)));
Announcer announcer = new Announcer(GalleryDetailScene.clreplaced).setArgs(args);
View thumb;
if (null != (thumb = view.findViewById(R.id.thumb))) {
announcer.setTranHelper(new EnterGalleryDetailTransaction(thumb));
}
startScene(announcer);
return true;
}
@Override
public boolean onItemLongClick(EasyRecyclerView parent, View view, int position, long id) {
final Context context = getContext2();
final MainActivity activity = getActivity2();
if (null == context || null == activity || null == mLazyList) {
return false;
}
final GalleryInfo gi = mLazyList.get(position);
new AlertDialog.Builder(context).setreplacedle(EhUtils.getSuitablereplacedle(gi)).sereplacedems(R.array.gallery_list_menu_entries, (dialog, which) -> {
switch(which) {
case // Download
0:
CommonOperations.startDownload(activity, gi, false);
break;
case // Favorites
1:
CommonOperations.addToFavorites(activity, gi);
showTip(R.string.add_to_favorite_success, LENGTH_SHORT);
break;
}
}).show();
return true;
}
private clreplaced HistoryHolder extends AbstractSwipeableItemViewHolder {
public final View card;
public final LoadImageView thumb;
public final TextView replacedle;
public final TextView uploader;
public final SimpleRatingView rating;
public final TextView category;
public final TextView posted;
public final TextView simpleLanguage;
public final TextView source;
public HistoryHolder(View itemView) {
super(itemView);
card = itemView.findViewById(R.id.card);
thumb = (LoadImageView) itemView.findViewById(R.id.thumb);
replacedle = (TextView) itemView.findViewById(R.id.replacedle);
uploader = (TextView) itemView.findViewById(R.id.uploader);
rating = (SimpleRatingView) itemView.findViewById(R.id.rating);
category = (TextView) itemView.findViewById(R.id.category);
posted = (TextView) itemView.findViewById(R.id.posted);
simpleLanguage = (TextView) itemView.findViewById(R.id.simple_language);
source = itemView.findViewById(R.id.source_bg);
}
@Override
public View getSwipeableContainerView() {
return card;
}
}
private clreplaced HistoryAdapter extends RecyclerView.Adapter<HistoryHolder> implements SwipeableItemAdapter<HistoryHolder> {
private final LayoutInflater mInflater;
private final int mListThumbWidth;
private final int mListThumbHeight;
public HistoryAdapter() {
mInflater = getLayoutInflater2();
View calculator = mInflater.inflate(R.layout.item_gallery_list_thumb_height, null);
ViewUtils.measureView(calculator, 1024, ViewGroup.LayoutParams.WRAP_CONTENT);
mListThumbHeight = calculator.getMeasuredHeight();
mListThumbWidth = mListThumbHeight * 2 / 3;
}
@Override
public long gereplacedemId(int position) {
if (null == mLazyList) {
return super.gereplacedemId(position);
} else {
return position;
}
}
@Override
public HistoryHolder onCreateViewHolder(ViewGroup parent, int viewType) {
HistoryHolder holder = new HistoryHolder(mInflater.inflate(R.layout.item_history, parent, false));
ViewGroup.LayoutParams lp = holder.thumb.getLayoutParams();
lp.width = mListThumbWidth;
lp.height = mListThumbHeight;
holder.thumb.setLayoutParams(lp);
return holder;
}
@Override
public void onBindViewHolder(HistoryHolder holder, int position) {
if (null == mLazyList) {
return;
}
GalleryInfo gi = mLazyList.get(position);
holder.thumb.load(EhCacheKeyFactory.getThumbKey(gi.gid), gi.thumb);
holder.replacedle.setText(EhUtils.getSuitablereplacedle(gi));
holder.uploader.setText(gi.uploader);
holder.rating.setRating(gi.rating);
TextView category = holder.category;
String newCategoryText = EhUtils.getCategory(gi.category);
if (!newCategoryText.equals(category.getText())) {
category.setText(newCategoryText);
category.setBackgroundColor(EhUtils.getCategoryColor(gi.category));
}
holder.posted.setText(gi.posted);
holder.simpleLanguage.setText(gi.simpleLanguage);
// Update transition name
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
String gid = gi.gid;
ViewCompat.setTransitionName(holder.thumb, TransitionNameFactory.getThumbTransitionName(gid));
}
holder.rating.setVisibility(View.INVISIBLE);
holder.category.setVisibility(View.INVISIBLE);
holder.source.setText(gi.source);
}
@Override
public int gereplacedemCount() {
return null != mLazyList ? mLazyList.size() : 0;
}
@Override
public int onGetSwipeReactionType(HistoryHolder holder, int position, int x, int y) {
return SwipeableItemConstants.REACTION_CAN_SWIPE_LEFT;
}
@Override
public void onSwipeItemStarted(HistoryHolder holder, int position) {
}
@Override
public void onSetSwipeBackground(HistoryHolder holder, int position, int type) {
}
@Override
public SwipeResultAction onSwipeItem(HistoryHolder holder, int position, int result) {
switch(result) {
case SwipeableItemConstants.RESULT_SWIPED_LEFT:
return new SwipeResultActionClear(position);
case SwipeableItemConstants.RESULT_SWIPED_RIGHT:
case SwipeableItemConstants.RESULT_CANCELED:
default:
return new SwipeResultActionDefault();
}
}
}
private clreplaced SwipeResultActionClear extends SwipeResultActionRemoveItem {
private final int mPosition;
protected SwipeResultActionClear(int position) {
mPosition = position;
}
@Override
protected void onPerformAction() {
super.onPerformAction();
if (null == mLazyList || null == mAdapter) {
return;
}
HistoryInfo info = mLazyList.get(mPosition);
EhDB.deleteHistoryInfo(info);
updateLazyList();
mAdapter.notifyDataSetChanged();
updateView(true);
}
}
}
18
Source : HistoryScene.java
with Apache License 2.0
from axlecho
with Apache License 2.0
from axlecho
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
if (null == mLazyList) {
return false;
}
Bundle args = new Bundle();
args.putString(GalleryDetailScene.KEY_ACTION, GalleryDetailScene.ACTION_GALLERY_INFO);
args.putParcelable(GalleryDetailScene.KEY_GALLERY_INFO, new GalleryInfo(mLazyList.get(position)));
Announcer announcer = new Announcer(GalleryDetailScene.clreplaced).setArgs(args);
View thumb;
if (null != (thumb = view.findViewById(R.id.thumb))) {
announcer.setTranHelper(new EnterGalleryDetailTransaction(thumb));
}
startScene(announcer);
return true;
}
18
Source : GalleryInfoScene.java
with Apache License 2.0
from axlecho
with Apache License 2.0
from axlecho
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
Context context = getContext2();
if (null != context && 0 != position && null != mValues) {
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
cmb.setPrimaryClip(ClipData.newPlainText(null, mValues.get(position)));
if (position == 3) {
// Save it to avoid detect the gallery
Settings.putClipboardTextHashCode(mValues.get(position).hashCode());
}
showTip(R.string.copied_to_clipboard, LENGTH_SHORT);
return true;
} else {
return false;
}
}
18
Source : PluginsActivity.java
with Apache License 2.0
from axlecho
with Apache License 2.0
from axlecho
public clreplaced PluginsActivity extends ToolbarActivity implements EasyRecyclerView.OnItemClickListener, View.OnClickListener {
private List<MHPlugin> data;
private EasyRecyclerView recyclerView;
private View tip;
private PluginsAdapter adapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
data = MHPluginManager.Companion.getINSTANCE().plugins();
setContentView(R.layout.activity_plugins);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
recyclerView = findViewById(R.id.recycler_view);
tip = findViewById(R.id.tip);
FloatingActionButton fab = findViewById(R.id.fab);
adapter = new PluginsAdapter();
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(this, R.attr.dividerColor), LayoutUtils.dp2pix(this, 1));
decoration.setShowLastDivider(true);
recyclerView.addItemDecoration(decoration);
recyclerView.setSelector(Ripple.generateRippleDrawable(this, !AttrResources.getAttrBoolean(this, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
recyclerView.setHasFixedSize(true);
recyclerView.setOnItemClickListener(this);
recyclerView.setPadding(recyclerView.getPaddingLeft(), recyclerView.getPaddingTop(), recyclerView.getPaddingRight(), recyclerView.getPaddingBottom() + getResources().getDimensionPixelOffset(R.dimen.gallery_padding_bottom_fab));
fab.setOnClickListener(this);
recyclerView.setVisibility(data.isEmpty() ? View.GONE : View.VISIBLE);
tip.setVisibility(data.isEmpty() ? View.VISIBLE : View.GONE);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.gereplacedemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onItemClick(EasyRecyclerView easyRecyclerView, View view, int position, long id) {
return true;
}
@Override
public void onClick(View v) {
importData(this);
}
private void notifyHostsChanges() {
data = MHPluginManager.Companion.getINSTANCE().plugins();
recyclerView.setVisibility(data.isEmpty() ? View.GONE : View.VISIBLE);
tip.setVisibility(data.isEmpty() ? View.VISIBLE : View.GONE);
adapter.notifyDataSetChanged();
}
private clreplaced HostsHolder extends RecyclerView.ViewHolder {
public final TextView host;
public final Switch enable;
public final View view;
public HostsHolder(View itemView) {
super(itemView);
host = itemView.findViewById(R.id.host);
enable = itemView.findViewById(R.id.enable);
view = itemView;
}
}
private clreplaced PluginsAdapter extends RecyclerView.Adapter<HostsHolder> {
private final LayoutInflater inflater = getLayoutInflater();
@NonNull
@Override
public HostsHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new HostsHolder(inflater.inflate(R.layout.item_plugin, parent, false));
}
@Override
public void onBindViewHolder(@NonNull HostsHolder holder, int position) {
MHPlugin plugin = data.get(position);
holder.host.setText(plugin.getName());
holder.enable.setChecked(plugin.isEnable());
holder.enable.setOnClickListener((view) -> {
plugin.setEnable(!plugin.isEnable());
MHPluginManager.Companion.getINSTANCE().savePlugin(plugin);
notifyItemChanged(position);
});
holder.view.setOnClickListener((view) -> {
plugin.setEnable(!plugin.isEnable());
MHPluginManager.Companion.getINSTANCE().savePlugin(plugin);
notifyItemChanged(position);
});
}
@Override
public int gereplacedemCount() {
return data.size();
}
}
private static void importData(final Context context) {
final File dir = AppConfig.getExternalDataPlugins();
if (null == dir) {
Toast.makeText(context, R.string.cant_get_data_dir, Toast.LENGTH_SHORT).show();
return;
}
final String[] files = dir.list();
if (null == files || files.length <= 0) {
Toast.makeText(context, R.string.cant_find_any_data, Toast.LENGTH_SHORT).show();
return;
}
Arrays.sort(files);
new AlertDialog.Builder(context).sereplacedems(files, (dialog, which) -> {
File file = new File(dir, files[which]);
try {
MHPlugin plugin = MHPluginManager.Companion.getINSTANCE().parserPlugin(file.getAbsolutePath());
MHPluginManager.Companion.getINSTANCE().savePlugin(plugin);
} catch (Exception e) {
Toast.makeText(context, e.getMessage(), Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(context, R.string.add_plugin_successful, Toast.LENGTH_SHORT).show();
}).show();
}
}
17
Source : QuickSearchScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
public final clreplaced QuickSearchScene extends ToolbarScene {
/*---------------
Whole life cycle
---------------*/
@Nullable
private List<QuickSearch> mQuickSearchList;
/*---------------
View life cycle
---------------*/
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private ViewTransition mViewTransition;
@Nullable
private RecyclerView.Adapter mAdapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mQuickSearchList = EhDB.getAllQuickSearch();
}
@Override
public void onDestroy() {
super.onDestroy();
mQuickSearchList = null;
}
@SuppressWarnings("deprecation")
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_label_list, container, false);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(view, R.id.recycler_view);
TextView tip = (TextView) ViewUtils.$$(view, R.id.tip);
mViewTransition = new ViewTransition(mRecyclerView, tip);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_search);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
tip.setText(R.string.no_quick_search);
// drag & drop manager
RecyclerViewDragDropManager dragDropManager = new RecyclerViewDragDropManager();
dragDropManager.setDraggingItemShadowDrawable((NinePatchDrawable) context.getResources().getDrawable(R.drawable.shadow_8dp));
RecyclerView.Adapter adapter = new QuickSearchAdapter();
adapter.setHreplacedtableIds(true);
// wrap for dragging
adapter = dragDropManager.createWrappedAdapter(adapter);
mAdapter = adapter;
final GeneralItemAnimator animator = new DraggableItemAnimator();
mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
mRecyclerView.setAdapter(adapter);
mRecyclerView.sereplacedemAnimator(animator);
dragDropManager.attachRecyclerView(mRecyclerView);
updateView();
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.quick_search);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
mViewTransition = null;
}
@Override
public void onNavigationClick() {
onBackPressed();
}
private void updateView() {
if (mViewTransition != null) {
if (mQuickSearchList != null && mQuickSearchList.size() > 0) {
mViewTransition.showView(0);
} else {
mViewTransition.showView(1);
}
}
}
private clreplaced QuickSearchHolder extends AbstractDraggableItemViewHolder implements View.OnClickListener {
public final TextView label;
public final View dragHandler;
public final View delete;
public QuickSearchHolder(View itemView) {
super(itemView);
label = (TextView) ViewUtils.$$(itemView, R.id.label);
dragHandler = ViewUtils.$$(itemView, R.id.drag_handler);
delete = ViewUtils.$$(itemView, R.id.delete);
delete.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int position = getAdapterPosition();
Context context = getContext2();
if (position == RecyclerView.NO_POSITION || mQuickSearchList == null) {
return;
}
final QuickSearch quickSearch = mQuickSearchList.get(position);
new AlertDialog.Builder(context).setreplacedle(R.string.delete_quick_search_replacedle).setMessage(getString(R.string.delete_quick_search_message, quickSearch.name)).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
EhDB.deleteQuickSearch(quickSearch);
mQuickSearchList.remove(position);
}
}).setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
if (null != mAdapter) {
mAdapter.notifyDataSetChanged();
}
updateView();
}
}).show();
}
}
private clreplaced QuickSearchAdapter extends RecyclerView.Adapter<QuickSearchHolder> implements DraggableItemAdapter<QuickSearchHolder> {
private final LayoutInflater mInflater;
public QuickSearchAdapter() {
mInflater = getLayoutInflater2();
replacedertUtils.replacedertNotNull(mInflater);
}
@Override
public QuickSearchHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new QuickSearchHolder(mInflater.inflate(R.layout.item_quick_search, parent, false));
}
@Override
public void onBindViewHolder(QuickSearchHolder holder, int position) {
if (mQuickSearchList != null) {
holder.label.setText(mQuickSearchList.get(position).name);
}
}
@Override
public long gereplacedemId(int position) {
return mQuickSearchList != null ? mQuickSearchList.get(position).getId() : 0;
}
@Override
public int gereplacedemCount() {
return mQuickSearchList != null ? mQuickSearchList.size() : 0;
}
@Override
public boolean onCheckCanStartDrag(QuickSearchHolder holder, int position, int x, int y) {
return ViewUtils.isViewUnder(holder.dragHandler, x, y, 0);
}
@Override
public ItemDraggableRange onGereplacedemDraggableRange(QuickSearchHolder holder, int position) {
return null;
}
@Override
public void onMoveItem(int fromPosition, int toPosition) {
if (fromPosition == toPosition) {
return;
}
if (null == mQuickSearchList) {
return;
}
EhDB.moveQuickSearch(fromPosition, toPosition);
final QuickSearch item = mQuickSearchList.remove(fromPosition);
mQuickSearchList.add(toPosition, item);
}
@Override
public boolean onCheckCanDrop(int draggingPosition, int dropPosition) {
return true;
}
@Override
public void onItemDragStarted(int position) {
}
@Override
public void onItemDragFinished(int fromPosition, int toPosition, boolean result) {
}
}
}
17
Source : HistoryScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
public clreplaced HistoryScene extends ToolbarScene implements EasyRecyclerView.OnItemClickListener, EasyRecyclerView.OnItemLongClickListener {
/*---------------
View life cycle
---------------*/
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private ViewTransition mViewTransition;
@Nullable
private RecyclerView.Adapter<?> mAdapter;
@Nullable
private LazyList<HistoryInfo> mLazyList;
@Override
public int getNavCheckedItem() {
return R.id.nav_history;
}
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_history, container, false);
View content = ViewUtils.$$(view, R.id.content);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(content, R.id.recycler_view);
FastScroller fastScroller = (FastScroller) ViewUtils.$$(content, R.id.fast_scroller);
TextView tip = (TextView) ViewUtils.$$(view, R.id.tip);
mViewTransition = new ViewTransition(content, tip);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
Resources resources = context.getResources();
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_history);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
RecyclerViewTouchActionGuardManager guardManager = new RecyclerViewTouchActionGuardManager();
guardManager.setInterceptVerticalScrollingWhileAnimationRunning(true);
guardManager.setEnabled(true);
RecyclerViewSwipeManager swipeManager = new RecyclerViewSwipeManager();
mAdapter = new HistoryAdapter();
mAdapter.setHreplacedtableIds(true);
mAdapter = swipeManager.createWrappedAdapter(mAdapter);
mRecyclerView.setAdapter(mAdapter);
final GeneralItemAnimator animator = new SwipeDismissItemAnimator();
animator.setSupportsChangeAnimations(false);
mRecyclerView.sereplacedemAnimator(animator);
AutoStaggeredGridLayoutManager layoutManager = new AutoStaggeredGridLayoutManager(0, StaggeredGridLayoutManager.VERTICAL);
layoutManager.setColumnSize(resources.getDimensionPixelOffset(Settings.getDetailSizeResId()));
layoutManager.setStrategy(AutoStaggeredGridLayoutManager.STRATEGY_MIN_SIZE);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
mRecyclerView.setDrawSelectorOnTop(true);
mRecyclerView.setClipToPadding(false);
mRecyclerView.setOnItemClickListener(this);
mRecyclerView.setOnItemLongClickListener(this);
int interval = resources.getDimensionPixelOffset(R.dimen.gallery_list_interval);
int paddingH = resources.getDimensionPixelOffset(R.dimen.gallery_list_margin_h);
int paddingV = resources.getDimensionPixelOffset(R.dimen.gallery_list_margin_v);
MarginItemDecoration decoration = new MarginItemDecoration(interval, paddingH, paddingV, paddingH, paddingV);
mRecyclerView.addItemDecoration(decoration);
decoration.applyPaddings(mRecyclerView);
guardManager.attachRecyclerView(mRecyclerView);
swipeManager.attachRecyclerView(mRecyclerView);
fastScroller.attachToRecyclerView(mRecyclerView);
HandlerDrawable handlerDrawable = new HandlerDrawable();
handlerDrawable.setColor(AttrResources.getAttrColor(context, R.attr.widgetColorThemeAccent));
fastScroller.setHandlerDrawable(handlerDrawable);
updateLazyList();
updateView(false);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.history);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mLazyList) {
mLazyList.close();
mLazyList = null;
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
}
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
mViewTransition = null;
mAdapter = null;
}
// Remember to notify
private void updateLazyList() {
LazyList<HistoryInfo> lazyList = EhDB.getHistoryLazyList();
if (mLazyList != null) {
mLazyList.close();
}
mLazyList = lazyList;
}
private void updateView(boolean animation) {
if (null == mAdapter || null == mViewTransition) {
return;
}
if (mAdapter.gereplacedemCount() == 0) {
mViewTransition.showView(1, animation);
} else {
mViewTransition.showView(0, animation);
}
}
@Override
public void onNavigationClick() {
onBackPressed();
}
@Override
public int getMenuResId() {
return R.menu.scene_history;
}
private void showClearAllDialog() {
new AlertDialog.Builder(getContext2()).setMessage(R.string.clear_all_history).setPositiveButton(R.string.clear_all, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (DialogInterface.BUTTON_POSITIVE != which || null == mAdapter) {
return;
}
EhDB.clearHistoryInfo();
updateLazyList();
mAdapter.notifyDataSetChanged();
updateView(true);
}
}).show();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
// Skip when in choice mode
Context context = getContext2();
if (null == context) {
return false;
}
int id = item.gereplacedemId();
switch(id) {
case R.id.action_clear_all:
{
showClearAllDialog();
return true;
}
}
return false;
}
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
if (null == mLazyList) {
return false;
}
Bundle args = new Bundle();
args.putString(GalleryDetailScene.KEY_ACTION, GalleryDetailScene.ACTION_GALLERY_INFO);
args.putParcelable(GalleryDetailScene.KEY_GALLERY_INFO, mLazyList.get(position));
Announcer announcer = new Announcer(GalleryDetailScene.clreplaced).setArgs(args);
View thumb;
if (null != (thumb = view.findViewById(R.id.thumb))) {
announcer.setTranHelper(new EnterGalleryDetailTransaction(thumb));
}
startScene(announcer);
return true;
}
@Override
public boolean onItemLongClick(EasyRecyclerView parent, View view, int position, long id) {
final Context context = getContext2();
final MainActivity activity = getActivity2();
if (null == context || null == activity || null == mLazyList) {
return false;
}
final GalleryInfo gi = mLazyList.get(position);
new AlertDialog.Builder(context).setreplacedle(EhUtils.getSuitablereplacedle(gi)).sereplacedems(R.array.gallery_list_menu_entries, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch(which) {
case // Download
0:
CommonOperations.startDownload(activity, gi, false);
break;
case // Favorites
1:
CommonOperations.addToFavorites(activity, gi, new addToFavoriteListener(context, activity.getStageId(), getTag()));
break;
}
}
}).show();
return true;
}
private clreplaced HistoryHolder extends AbstractSwipeableItemViewHolder {
public final View card;
public final LoadImageView thumb;
public final TextView replacedle;
public final TextView uploader;
public final SimpleRatingView rating;
public final TextView category;
public final TextView posted;
public final TextView simpleLanguage;
public HistoryHolder(View itemView) {
super(itemView);
card = itemView.findViewById(R.id.card);
thumb = (LoadImageView) itemView.findViewById(R.id.thumb);
replacedle = (TextView) itemView.findViewById(R.id.replacedle);
uploader = (TextView) itemView.findViewById(R.id.uploader);
rating = (SimpleRatingView) itemView.findViewById(R.id.rating);
category = (TextView) itemView.findViewById(R.id.category);
posted = (TextView) itemView.findViewById(R.id.posted);
simpleLanguage = (TextView) itemView.findViewById(R.id.simple_language);
}
@Override
public View getSwipeableContainerView() {
return card;
}
}
private clreplaced HistoryAdapter extends RecyclerView.Adapter<HistoryHolder> implements SwipeableItemAdapter<HistoryHolder> {
private final LayoutInflater mInflater;
private final int mListThumbWidth;
private final int mListThumbHeight;
public HistoryAdapter() {
mInflater = getLayoutInflater2();
View calculator = mInflater.inflate(R.layout.item_gallery_list_thumb_height, null);
ViewUtils.measureView(calculator, 1024, ViewGroup.LayoutParams.WRAP_CONTENT);
mListThumbHeight = calculator.getMeasuredHeight();
mListThumbWidth = mListThumbHeight * 2 / 3;
}
@Override
public long gereplacedemId(int position) {
if (null == mLazyList) {
return super.gereplacedemId(position);
} else {
return mLazyList.get(position).gid;
}
}
@Override
public HistoryHolder onCreateViewHolder(ViewGroup parent, int viewType) {
HistoryHolder holder = new HistoryHolder(mInflater.inflate(R.layout.item_history, parent, false));
ViewGroup.LayoutParams lp = holder.thumb.getLayoutParams();
lp.width = mListThumbWidth;
lp.height = mListThumbHeight;
holder.thumb.setLayoutParams(lp);
return holder;
}
@Override
public void onBindViewHolder(HistoryHolder holder, int position) {
if (null == mLazyList) {
return;
}
GalleryInfo gi = mLazyList.get(position);
holder.thumb.load(EhCacheKeyFactory.getThumbKey(gi.gid), gi.thumb);
holder.replacedle.setText(EhUtils.getSuitablereplacedle(gi));
holder.uploader.setText(gi.uploader);
holder.rating.setRating(gi.rating);
TextView category = holder.category;
String newCategoryText = EhUtils.getCategory(gi.category);
if (!newCategoryText.equals(category.getText())) {
category.setText(newCategoryText);
category.setBackgroundColor(EhUtils.getCategoryColor(gi.category));
}
holder.posted.setText(gi.posted);
holder.simpleLanguage.setText(gi.simpleLanguage);
// Update transition name
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
long gid = gi.gid;
ViewCompat.setTransitionName(holder.thumb, TransitionNameFactory.getThumbTransitionName(gid));
}
}
@Override
public int gereplacedemCount() {
return null != mLazyList ? mLazyList.size() : 0;
}
@Override
public int onGetSwipeReactionType(HistoryHolder holder, int position, int x, int y) {
return SwipeableItemConstants.REACTION_CAN_SWIPE_LEFT;
}
@Override
public void onSwipeItemStarted(HistoryHolder holder, int position) {
}
@Override
public void onSetSwipeBackground(HistoryHolder holder, int position, int type) {
}
@Override
public SwipeResultAction onSwipeItem(HistoryHolder holder, int position, int result) {
switch(result) {
case SwipeableItemConstants.RESULT_SWIPED_LEFT:
return new SwipeResultActionClear(position);
case SwipeableItemConstants.RESULT_SWIPED_RIGHT:
case SwipeableItemConstants.RESULT_CANCELED:
default:
return new SwipeResultActionDefault();
}
}
}
private clreplaced SwipeResultActionClear extends SwipeResultActionRemoveItem {
private final int mPosition;
protected SwipeResultActionClear(int position) {
mPosition = position;
}
@Override
protected void onPerformAction() {
super.onPerformAction();
if (null == mLazyList || null == mAdapter) {
return;
}
HistoryInfo info = mLazyList.get(mPosition);
EhDB.deleteHistoryInfo(info);
updateLazyList();
mAdapter.notifyDataSetChanged();
updateView(true);
}
}
private static clreplaced addToFavoriteListener extends EhCallback<HistoryScene, Void> {
public addToFavoriteListener(Context context, int stageId, String sceneTag) {
super(context, stageId, sceneTag);
}
@Override
public void onSuccess(Void result) {
showTip(R.string.add_to_favorite_success, LENGTH_SHORT);
}
@Override
public void onFailure(Exception e) {
showTip(R.string.add_to_favorite_failure, LENGTH_LONG);
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof HistoryScene;
}
}
}
17
Source : GalleryPreviewsScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
Context context = getContext2();
if (null != context && null != mHelper && null != mGalleryInfo) {
GalleryPreview p = mHelper.getDataAtEx(position);
if (p != null) {
Intent intent = new Intent(context, GalleryActivity.clreplaced);
intent.setAction(GalleryActivity.ACTION_EH);
intent.putExtra(GalleryActivity.KEY_GALLERY_INFO, mGalleryInfo);
intent.putExtra(GalleryActivity.KEY_PAGE, p.getPosition());
startActivity(intent);
}
}
return true;
}
17
Source : GalleryCommentsScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
/**
* 画廊评论对象
*/
public final clreplaced GalleryCommentsScene extends ToolbarScene implements EasyRecyclerView.OnItemClickListener, View.OnClickListener {
public static final String TAG = GalleryCommentsScene.clreplaced.getSimpleName();
public static final String KEY_API_UID = "api_uid";
public static final String KEY_API_KEY = "api_key";
public static final String KEY_GID = "gid";
public static final String KEY_TOKEN = "token";
public static final String KEY_COMMENT_LIST = "comment_list";
private long mApiUid;
private String mApiKey;
private long mGid;
private String mToken;
@Nullable
private GalleryCommentList mCommentList;
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private FabLayout mFabLayout;
@Nullable
private FloatingActionButton mFab;
@Nullable
private View mEditPanel;
@Nullable
private ImageView mSendImage;
@Nullable
private EditText mEditText;
@Nullable
private CommentAdapter mAdapter;
@Nullable
private ViewTransition mViewTransition;
private Drawable mSendDrawable;
private Drawable mPencilDrawable;
private long mCommentId;
private boolean mInAnimation = false;
private boolean mShowAllComments = false;
private boolean mRefreshingComments = false;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void handleArgs(Bundle args) {
if (args == null) {
return;
}
mApiUid = args.getLong(KEY_API_UID, -1L);
mApiKey = args.getString(KEY_API_KEY);
mGid = args.getLong(KEY_GID, -1L);
mToken = args.getString(KEY_TOKEN, null);
mCommentList = args.getParcelable(KEY_COMMENT_LIST);
mShowAllComments = mCommentList != null && !mCommentList.hasMore;
}
private void onInit() {
handleArgs(getArguments());
}
private void onRestore(@NonNull Bundle savedInstanceState) {
mApiUid = savedInstanceState.getLong(KEY_API_UID, -1L);
mApiKey = savedInstanceState.getString(KEY_API_KEY);
mGid = savedInstanceState.getLong(KEY_GID, -1L);
mToken = savedInstanceState.getString(KEY_TOKEN, null);
mCommentList = savedInstanceState.getParcelable(KEY_COMMENT_LIST);
mShowAllComments = mCommentList != null && !mCommentList.hasMore;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(KEY_API_UID, mApiUid);
outState.putString(KEY_API_KEY, mApiKey);
outState.putLong(KEY_GID, mGid);
outState.putString(KEY_TOKEN, mToken);
outState.putParcelable(KEY_COMMENT_LIST, mCommentList);
}
/**
* 评论详情页创建
* @param inflater
* @param container
* @param savedInstanceState
* @return
*/
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_gallery_comments, container, false);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(view, R.id.recycler_view);
TextView tip = (TextView) ViewUtils.$$(view, R.id.tip);
mEditPanel = ViewUtils.$$(view, R.id.edit_panel);
mSendImage = (ImageView) ViewUtils.$$(mEditPanel, R.id.send);
mEditText = (EditText) ViewUtils.$$(mEditPanel, R.id.edit_text);
mFabLayout = (FabLayout) ViewUtils.$$(view, R.id.fab_layout);
mFab = (FloatingActionButton) ViewUtils.$$(view, R.id.fab);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
Resources resources = context.getResources();
int paddingBottomFab = resources.getDimensionPixelOffset(R.dimen.gallery_padding_bottom_fab);
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_sad_pandroid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
mSendDrawable = DrawableManager.getVectorDrawable(context, R.drawable.v_send_dark_x24);
mPencilDrawable = DrawableManager.getVectorDrawable(context, R.drawable.v_pencil_dark_x24);
mAdapter = new CommentAdapter();
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setShowLastDivider(true);
mRecyclerView.addItemDecoration(decoration);
mRecyclerView.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setOnItemClickListener(this);
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), mRecyclerView.getPaddingBottom() + paddingBottomFab);
// Cancel change animator
RecyclerView.ItemAnimator itemAnimator = mRecyclerView.gereplacedemAnimator();
if (itemAnimator instanceof DefaulreplacedemAnimator) {
((DefaulreplacedemAnimator) itemAnimator).setSupportsChangeAnimations(false);
}
mSendImage.setOnClickListener(this);
mFab.setOnClickListener(this);
addAboveSnackView(mEditPanel);
addAboveSnackView(mFabLayout);
mViewTransition = new ViewTransition(mRecyclerView, tip);
updateView(false);
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
if (null != mEditPanel) {
removeAboveSnackView(mEditPanel);
mEditPanel = null;
}
if (null != mFabLayout) {
removeAboveSnackView(mFabLayout);
mFabLayout = null;
}
mFab = null;
mSendImage = null;
mEditText = null;
mAdapter = null;
mViewTransition = null;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.gallery_comments);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onNavigationClick() {
onBackPressed();
}
private void voteComment(long id, int vote) {
Context context = getContext2();
MainActivity activity = getActivity2();
if (null == context || null == activity) {
return;
}
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_VOTE_COMMENT).setArgs(mApiUid, mApiKey, mGid, mToken, id, vote).setCallback(new VoteCommentListener(context, activity.getStageId(), getTag()));
EhApplication.getEhClient(context).execute(request);
}
private clreplaced 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);
}
}
@SuppressLint("InflateParams")
public void showVoteStatusDialog(Context context, String voteStatus) {
String[] temp = StringUtils.split(voteStatus, ',');
final int length = temp.length;
final String[] userArray = new String[length];
final String[] voteArray = new String[length];
for (int i = 0; i < length; i++) {
String str = StringUtils.trim(temp[i]);
int index = str.lastIndexOf(' ');
if (index < 0) {
Log.d(TAG, "Something wrong happened about vote state");
userArray[i] = str;
voteArray[i] = "";
} else {
userArray[i] = StringUtils.trim(str.substring(0, index));
voteArray[i] = StringUtils.trim(str.substring(index + 1));
}
}
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 RecyclerView.Adapter<InfoHolder>() {
@Override
public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new InfoHolder(inflater.inflate(R.layout.item_drawer_favorites, parent, false));
}
@Override
public void onBindViewHolder(InfoHolder holder, int position) {
holder.key.setText(userArray[position]);
holder.value.setText(voteArray[position]);
}
@Override
public int gereplacedemCount() {
return length;
}
});
rv.setLayoutManager(new LinearLayoutManager(context));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setPadding(ResourcesUtils.getAttrDimensionPixelOffset(context, R.attr.dialogPreferredPadding));
rv.addItemDecoration(decoration);
rv.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
rv.setClipToPadding(false);
builder.setView(rv).show();
}
private void showCommentDialog(int position) {
final Context context = getContext2();
if (context == null || mCommentList == null || mCommentList.comments == null || position >= mCommentList.comments.length || position < 0) {
return;
}
final GalleryComment comment = mCommentList.comments[position];
List<String> menu = new ArrayList<>();
final IntList menuId = new IntList();
Resources resources = context.getResources();
menu.add(resources.getString(R.string.copy_comment_text));
menuId.add(R.id.copy);
menu.add(resources.getString(R.string.join_in_blacklist));
menuId.add(R.id.join_blacklist);
if (comment.editable) {
menu.add(resources.getString(R.string.edit_comment));
menuId.add(R.id.edit_comment);
}
if (comment.voteUpAble) {
menu.add(resources.getString(comment.voteUpEd ? R.string.cancel_vote_up : R.string.vote_up));
menuId.add(R.id.vote_up);
}
if (comment.voteDownAble) {
menu.add(resources.getString(comment.voteDownEd ? R.string.cancel_vote_down : R.string.vote_down));
menuId.add(R.id.vote_down);
}
if (!TextUtils.isEmpty(comment.voteState)) {
menu.add(resources.getString(R.string.check_vote_status));
menuId.add(R.id.check_vote_status);
}
new AlertDialog.Builder(context).sereplacedems(menu.toArray(new String[menu.size()]), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which < 0 || which >= menuId.size()) {
return;
}
int id = menuId.get(which);
switch(id) {
case R.id.copy:
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
cmb.setPrimaryClip(ClipData.newPlainText(null, comment.comment));
showTip(R.string.copied_to_clipboard, LENGTH_SHORT);
break;
case R.id.vote_up:
voteComment(comment.id, 1);
break;
case R.id.vote_down:
voteComment(comment.id, -1);
break;
case R.id.check_vote_status:
showVoteStatusDialog(context, comment.voteState);
break;
case R.id.edit_comment:
prepareEditComment(comment.id);
if (!mInAnimation && mEditPanel != null && mEditPanel.getVisibility() != View.VISIBLE) {
showEditPanel(true);
}
break;
case R.id.join_blacklist:
EhDB.insertBlackList(BlackListUtils.parseBlacklist(comment));
mCommentList.DeleteComment(position);
mAdapter.notifyDataSetChanged();
updateView(true);
break;
}
}
}).show();
}
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
MainActivity activity = getActivity2();
if (null == activity) {
return false;
}
RecyclerView.ViewHolder holder = parent.getChildViewHolder(view);
if (holder instanceof ActualCommentHolder) {
ActualCommentHolder commentHolder = (ActualCommentHolder) holder;
ClickableSpan span = commentHolder.comment.getCurrentSpan();
commentHolder.comment.clearCurrentSpan();
if (span instanceof URLSpan) {
UrlOpener.openUrl(activity, ((URLSpan) span).getURL(), true);
} else {
showCommentDialog(position);
}
} else if (holder instanceof MoreCommentHolder && !mRefreshingComments && mAdapter != null) {
mRefreshingComments = true;
mShowAllComments = true;
mAdapter.notifyItemChanged(position);
String url = getGalleryDetailUrl();
if (url != null) {
// Request
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_GET_GALLERY_DETAIL).setArgs(url).setCallback(new RefreshCommentListener(activity, activity.getStageId(), getTag()));
EhApplication.getEhClient(activity).execute(request);
}
}
return true;
}
private void updateView(boolean animation) {
if (null == mViewTransition) {
return;
}
if (mCommentList == null || mCommentList.comments == null || mCommentList.comments.length <= 0) {
mViewTransition.showView(1, animation);
} else {
mViewTransition.showView(0, animation);
}
}
private void prepareNewComment() {
mCommentId = 0;
if (mSendImage != null) {
mSendImage.setImageDrawable(mSendDrawable);
}
}
private void prepareEditComment(long commentId) {
mCommentId = commentId;
if (mSendImage != null) {
mSendImage.setImageDrawable(mPencilDrawable);
}
}
private void showEditPanelWithAnimation() {
if (null == mFab || null == mEditPanel) {
return;
}
mInAnimation = true;
mFab.setTranslationX(0.0f);
mFab.setTranslationY(0.0f);
mFab.setScaleX(1.0f);
mFab.setScaleY(1.0f);
int fabEndX = mEditPanel.getLeft() + (mEditPanel.getWidth() / 2) - (mFab.getWidth() / 2);
int fabEndY = mEditPanel.getTop() + (mEditPanel.getHeight() / 2) - (mFab.getHeight() / 2);
mFab.animate().x(fabEndX).y(fabEndY).scaleX(0.0f).scaleY(0.0f).setInterpolator(AnimationUtils.SLOW_FAST_SLOW_INTERPOLATOR).setDuration(300L).setListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
if (null == mFab || null == mEditPanel) {
return;
}
((View) mFab).setVisibility(View.INVISIBLE);
mEditPanel.setVisibility(View.VISIBLE);
int halfW = mEditPanel.getWidth() / 2;
int halfH = mEditPanel.getHeight() / 2;
Animator animator = ViewAnimationUtils.createCircularReveal(mEditPanel, halfW, halfH, 0, (float) Math.hypot(halfW, halfH)).setDuration(300L);
animator.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator a) {
mInAnimation = false;
}
});
animator.start();
}
}).start();
}
private void showEditPanel(boolean animation) {
if (animation) {
showEditPanelWithAnimation();
} else {
if (null == mFab || null == mEditPanel) {
return;
}
((View) mFab).setVisibility(View.INVISIBLE);
mEditPanel.setVisibility(View.VISIBLE);
}
}
private void hideEditPanelWithAnimation() {
if (null == mFab || null == mEditPanel) {
return;
}
mInAnimation = true;
int halfW = mEditPanel.getWidth() / 2;
int halfH = mEditPanel.getHeight() / 2;
Animator animator = ViewAnimationUtils.createCircularReveal(mEditPanel, halfW, halfH, (float) Math.hypot(halfW, halfH), 0.0f).setDuration(300L);
animator.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator a) {
if (null == mFab || null == mEditPanel) {
return;
}
if (Looper.myLooper() != Looper.getMainLooper()) {
// Some devices may run this block in non-UI thread.
// It might be a bug of Android OS.
// Check it here to avoid crash.
return;
}
mEditPanel.setVisibility(View.GONE);
((View) mFab).setVisibility(View.VISIBLE);
int fabStartX = mEditPanel.getLeft() + (mEditPanel.getWidth() / 2) - (mFab.getWidth() / 2);
int fabStartY = mEditPanel.getTop() + (mEditPanel.getHeight() / 2) - (mFab.getHeight() / 2);
mFab.setX(fabStartX);
mFab.setY(fabStartY);
mFab.setScaleX(0.0f);
mFab.setScaleY(0.0f);
mFab.setRotation(-45.0f);
mFab.animate().translationX(0.0f).translationY(0.0f).scaleX(1.0f).scaleY(1.0f).rotation(0.0f).setInterpolator(AnimationUtils.SLOW_FAST_SLOW_INTERPOLATOR).setDuration(300L).setListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
mInAnimation = false;
}
}).start();
}
});
animator.start();
}
private void hideEditPanel(boolean animation) {
if (animation) {
hideEditPanelWithAnimation();
} else {
if (null == mFab || null == mEditPanel) {
return;
}
((View) mFab).setVisibility(View.VISIBLE);
mEditPanel.setVisibility(View.INVISIBLE);
}
}
@Nullable
private String getGalleryDetailUrl() {
if (mGid != -1 && mToken != null) {
return EhUrl.getGalleryDetailUrl(mGid, mToken, 0, mShowAllComments);
} else {
return null;
}
}
/**
* 点击发送评论按钮时触发
* @param v
*/
@Override
public void onClick(View v) {
Context context = getContext2();
MainActivity activity = getActivity2();
if (null == context || null == activity || null == mEditText) {
return;
}
if (mFab == v) {
if (!mInAnimation) {
prepareNewComment();
showEditPanel(true);
}
} else if (mSendImage == v) {
if (!mInAnimation) {
String comment = mEditText.getText().toString();
if (TextUtils.isEmpty(comment)) {
// Comment is empty
return;
}
String url = getGalleryDetailUrl();
if (url == null) {
return;
}
// Request
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_GET_COMMENT_GALLERY).setArgs(url, comment, mCommentId != 0 ? Long.toString(mCommentId) : null).setCallback(new CommentGalleryListener(context, activity.getStageId(), getTag(), mCommentId));
EhApplication.getEhClient(context).execute(request);
hideSoftInput();
hideEditPanel(true);
}
}
}
/**
* 点击评论详情页右上角返回图标时触发
*/
@Override
public void onBackPressed() {
if (mInAnimation) {
return;
}
if (null != mEditPanel && mEditPanel.getVisibility() == View.VISIBLE) {
hideEditPanel(true);
} else {
finish();
}
}
private static final int TYPE_COMMENT = 0;
private static final int TYPE_MORE = 1;
private static final int TYPE_PROGRESS = 2;
private abstract clreplaced CommentHolder extends RecyclerView.ViewHolder {
public CommentHolder(LayoutInflater inflater, int resId, ViewGroup parent) {
super(inflater.inflate(resId, parent, false));
}
}
private clreplaced ActualCommentHolder extends CommentHolder {
private final TextView user;
private final TextView time;
private final LinkifyTextView comment;
public ActualCommentHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater, R.layout.item_gallery_comment, parent);
user = itemView.findViewById(R.id.user);
time = itemView.findViewById(R.id.time);
comment = itemView.findViewById(R.id.comment);
}
private CharSequence generateComment(Context context, ObservedTextView textView, GalleryComment comment) {
SpannableStringBuilder ssb = Html.fromHtml(comment.comment, new URLImageGetter(textView, EhApplication.getConaco(context)), null);
if (0 != comment.id && 0 != comment.score) {
int score = comment.score;
String scoreString = score > 0 ? "+" + score : Integer.toString(score);
SpannableString ss = new SpannableString(scoreString);
ss.setSpan(new RelativeSizeSpan(0.8f), 0, scoreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new StyleSpan(Typeface.BOLD), 0, scoreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new ForegroundColorSpan(AttrResources.getAttrColor(context, android.R.attr.textColorSecondary)), 0, scoreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append(" ").append(ss);
}
if (comment.lastEdited != 0) {
String str = context.getString(R.string.last_edited, ReadableTime.getTimeAgo(comment.lastEdited));
SpannableString ss = new SpannableString(str);
ss.setSpan(new RelativeSizeSpan(0.8f), 0, str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new StyleSpan(Typeface.BOLD), 0, str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new ForegroundColorSpan(AttrResources.getAttrColor(context, android.R.attr.textColorSecondary)), 0, str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append("\n\n").append(ss);
}
return TextUrl.handleTextUrl(ssb);
}
public void bind(GalleryComment value) {
user.setText(value.user);
time.setText(ReadableTime.getTimeAgo(value.time));
comment.setText(generateComment(comment.getContext(), comment, value));
}
}
private clreplaced MoreCommentHolder extends CommentHolder {
public MoreCommentHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater, R.layout.item_gallery_comment_more, parent);
}
}
private clreplaced ProgressCommentHolder extends CommentHolder {
public ProgressCommentHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater, R.layout.item_gallery_comment_progress, parent);
}
}
private clreplaced CommentAdapter extends RecyclerView.Adapter<CommentHolder> {
private final LayoutInflater mInflater;
public CommentAdapter() {
mInflater = getLayoutInflater2();
replacedertUtils.replacedertNotNull(mInflater);
}
@Override
public CommentHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
switch(viewType) {
case TYPE_COMMENT:
return new ActualCommentHolder(mInflater, parent);
case TYPE_MORE:
return new MoreCommentHolder(mInflater, parent);
case TYPE_PROGRESS:
return new ProgressCommentHolder(mInflater, parent);
default:
throw new IllegalStateException("Invalid view type: " + viewType);
}
}
@Override
public void onBindViewHolder(@NonNull CommentHolder holder, int position) {
Context context = getContext2();
if (context == null || mCommentList == null) {
return;
}
if (holder instanceof ActualCommentHolder) {
((ActualCommentHolder) holder).bind(mCommentList.comments[position]);
}
}
@Override
public int gereplacedemCount() {
if (mCommentList == null || mCommentList.comments == null) {
return 0;
} else if (mCommentList.hasMore) {
return mCommentList.comments.length + 1;
} else {
return mCommentList.comments.length;
}
}
@Override
public int gereplacedemViewType(int position) {
if (position >= mCommentList.comments.length) {
return mRefreshingComments ? TYPE_PROGRESS : TYPE_MORE;
} else {
return TYPE_COMMENT;
}
}
}
private void onRefreshGallerySuccess(GalleryCommentList result) {
if (mAdapter == null) {
return;
}
mRefreshingComments = false;
mCommentList = result;
mAdapter.notifyDataSetChanged();
updateView(true);
Bundle re = new Bundle();
re.putParcelable(KEY_COMMENT_LIST, result);
setResult(SceneFragment.RESULT_OK, re);
}
private void onRefreshGalleryFailure() {
if (mAdapter == null) {
return;
}
mRefreshingComments = false;
int position = mAdapter.gereplacedemCount() - 1;
if (position >= 0) {
mAdapter.notifyItemChanged(position);
}
}
private void onCommentGallerySuccess(GalleryCommentList result) {
if (mAdapter == null) {
return;
}
mCommentList = result;
mAdapter.notifyDataSetChanged();
Bundle re = new Bundle();
re.putParcelable(KEY_COMMENT_LIST, result);
setResult(SceneFragment.RESULT_OK, re);
// Remove text
if (mEditText != null) {
mEditText.setText("");
}
updateView(true);
}
private void onVoteCommentSuccess(VoteCommentParser.Result result) {
if (mAdapter == null || mCommentList == null || mCommentList.comments == null) {
return;
}
int position = -1;
for (int i = 0, n = mCommentList.comments.length; i < n; i++) {
GalleryComment comment = mCommentList.comments[i];
if (comment.id == result.id) {
position = i;
break;
}
}
if (-1 == position) {
Log.d(TAG, "Can't find comment with id " + result.id);
return;
}
// Update comment
GalleryComment comment = mCommentList.comments[position];
comment.score = result.score;
if (result.expectVote > 0) {
comment.voteUpEd = 0 != result.vote;
comment.voteDownEd = false;
} else {
comment.voteDownEd = 0 != result.vote;
comment.voteUpEd = false;
}
mAdapter.notifyItemChanged(position);
Bundle re = new Bundle();
re.putParcelable(KEY_COMMENT_LIST, mCommentList);
setResult(SceneFragment.RESULT_OK, re);
}
private static clreplaced RefreshCommentListener extends EhCallback<GalleryCommentsScene, GalleryDetail> {
public RefreshCommentListener(Context context, int stageId, String sceneTag) {
super(context, stageId, sceneTag);
}
@Override
public void onSuccess(GalleryDetail result) {
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onRefreshGallerySuccess(result.comments);
}
}
@Override
public void onFailure(Exception e) {
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onRefreshGalleryFailure();
}
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryCommentsScene;
}
}
private static clreplaced CommentGalleryListener extends EhCallback<GalleryCommentsScene, GalleryCommentList> {
private long mCommentId;
public CommentGalleryListener(Context context, int stageId, String sceneTag, long commentId) {
super(context, stageId, sceneTag);
mCommentId = commentId;
}
@Override
public void onSuccess(GalleryCommentList result) {
showTip(mCommentId != 0 ? R.string.edit_comment_successfully : R.string.comment_successfully, LENGTH_SHORT);
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onCommentGallerySuccess(result);
}
}
@Override
public void onFailure(Exception e) {
showTip(getContent().getString(mCommentId != 0 ? R.string.edit_comment_failed : R.string.comment_failed) + "\n" + ExceptionUtils.getReadableString(e), LENGTH_LONG);
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryCommentsScene;
}
}
private static clreplaced VoteCommentListener extends EhCallback<GalleryCommentsScene, VoteCommentParser.Result> {
public VoteCommentListener(Context context, int stageId, String sceneTag) {
super(context, stageId, sceneTag);
}
@Override
public void onSuccess(VoteCommentParser.Result result) {
showTip(result.expectVote > 0 ? (0 != result.vote ? R.string.vote_up_successfully : R.string.cancel_vote_up_successfully) : (0 != result.vote ? R.string.vote_down_successfully : R.string.cancel_vote_down_successfully), LENGTH_SHORT);
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onVoteCommentSuccess(result);
}
}
@Override
public void onFailure(Exception e) {
showTip(R.string.vote_failed, LENGTH_LONG);
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryCommentsScene;
}
}
}
17
Source : GalleryCommentsScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
@SuppressLint("InflateParams")
public void showVoteStatusDialog(Context context, String voteStatus) {
String[] temp = StringUtils.split(voteStatus, ',');
final int length = temp.length;
final String[] userArray = new String[length];
final String[] voteArray = new String[length];
for (int i = 0; i < length; i++) {
String str = StringUtils.trim(temp[i]);
int index = str.lastIndexOf(' ');
if (index < 0) {
Log.d(TAG, "Something wrong happened about vote state");
userArray[i] = str;
voteArray[i] = "";
} else {
userArray[i] = StringUtils.trim(str.substring(0, index));
voteArray[i] = StringUtils.trim(str.substring(index + 1));
}
}
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 RecyclerView.Adapter<InfoHolder>() {
@Override
public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new InfoHolder(inflater.inflate(R.layout.item_drawer_favorites, parent, false));
}
@Override
public void onBindViewHolder(InfoHolder holder, int position) {
holder.key.setText(userArray[position]);
holder.value.setText(voteArray[position]);
}
@Override
public int gereplacedemCount() {
return length;
}
});
rv.setLayoutManager(new LinearLayoutManager(context));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setPadding(ResourcesUtils.getAttrDimensionPixelOffset(context, R.attr.dialogPreferredPadding));
rv.addItemDecoration(decoration);
rv.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
rv.setClipToPadding(false);
builder.setView(rv).show();
}
17
Source : DownloadsScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
@Override
public boolean onItemLongClick(EasyRecyclerView parent, View view, int position, long id) {
EasyRecyclerView recyclerView = mRecyclerView;
if (recyclerView == null) {
return false;
}
if (!recyclerView.isInCustomChoice()) {
recyclerView.intoCustomChoiceMode();
}
recyclerView.toggleItemChecked(position);
return true;
}
17
Source : DownloadLabelsScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
public clreplaced DownloadLabelsScene extends ToolbarScene {
/*---------------
Whole life cycle
---------------*/
@Nullable
public List<DownloadLabel> mList = null;
/*---------------
View life cycle
---------------*/
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private ViewTransition mViewTransition;
@Nullable
private RecyclerView.Adapter mAdapter;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mList = EhApplication.getDownloadManager(getContext2()).getLabelList();
}
@Override
public void onDestroy() {
super.onDestroy();
mList = null;
}
@SuppressWarnings("deprecation")
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_label_list, container, false);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(view, R.id.recycler_view);
TextView tip = (TextView) ViewUtils.$$(view, R.id.tip);
mViewTransition = new ViewTransition(mRecyclerView, tip);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_label);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
tip.setText(R.string.no_download_label);
// drag & drop manager
RecyclerViewDragDropManager dragDropManager = new RecyclerViewDragDropManager();
dragDropManager.setDraggingItemShadowDrawable((NinePatchDrawable) context.getResources().getDrawable(R.drawable.shadow_8dp));
RecyclerView.Adapter adapter = new LabelAdapter();
adapter.setHreplacedtableIds(true);
// wrap for dragging
adapter = dragDropManager.createWrappedAdapter(adapter);
mAdapter = adapter;
final GeneralItemAnimator animator = new SwipeDismissItemAnimator();
mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
mRecyclerView.setAdapter(adapter);
mRecyclerView.sereplacedemAnimator(animator);
dragDropManager.attachRecyclerView(mRecyclerView);
updateView();
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.download_labels);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
mViewTransition = null;
mAdapter = null;
}
@Override
public void onNavigationClick() {
onBackPressed();
}
@Override
public int getMenuResId() {
return R.menu.scene_download_label;
}
@Override
public boolean onMenuItemClick(MenuItem item) {
Context context = getContext2();
if (null == context) {
return false;
}
int id = item.gereplacedemId();
switch(id) {
case R.id.action_add:
{
EditTextDialogBuilder builder = new EditTextDialogBuilder(context, null, getString(R.string.download_labels));
builder.setreplacedle(R.string.new_label_replacedle);
builder.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.show();
new NewLabelDialogHelper(builder, dialog);
}
}
return false;
}
private void updateView() {
if (mViewTransition != null) {
if (mList != null && mList.size() > 0) {
mViewTransition.showView(0);
} else {
mViewTransition.showView(1);
}
}
}
private clreplaced NewLabelDialogHelper implements View.OnClickListener {
private final EditTextDialogBuilder mBuilder;
private final AlertDialog mDialog;
public NewLabelDialogHelper(EditTextDialogBuilder builder, AlertDialog dialog) {
mBuilder = builder;
mDialog = dialog;
Button button = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (button != null) {
button.setOnClickListener(this);
}
}
@Override
public void onClick(View v) {
Context context = getContext2();
if (null == context) {
return;
}
String text = mBuilder.getText();
if (TextUtils.isEmpty(text)) {
mBuilder.setError(getString(R.string.label_text_is_empty));
} else if (getString(R.string.default_download_label_name).equals(text)) {
mBuilder.setError(getString(R.string.label_text_is_invalid));
} else if (EhApplication.getDownloadManager(context).containLabel(text)) {
mBuilder.setError(getString(R.string.label_text_exist));
} else {
mBuilder.setError(null);
mDialog.dismiss();
EhApplication.getDownloadManager(context).addLabel(text);
if (mAdapter != null && mList != null) {
mAdapter.notifyItemInserted(mList.size() - 1);
}
if (mViewTransition != null) {
if (mList != null && mList.size() > 0) {
mViewTransition.showView(0);
} else {
mViewTransition.showView(1);
}
}
}
}
}
private clreplaced RenameLabelDialogHelper implements View.OnClickListener {
private final EditTextDialogBuilder mBuilder;
private final AlertDialog mDialog;
private final String mOriginalLabel;
private final int mPosition;
public RenameLabelDialogHelper(EditTextDialogBuilder builder, AlertDialog dialog, String originalLabel, int position) {
mBuilder = builder;
mDialog = dialog;
mOriginalLabel = originalLabel;
mPosition = position;
Button button = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (button != null) {
button.setOnClickListener(this);
}
}
@Override
public void onClick(View v) {
Context context = getContext2();
if (null == context) {
return;
}
String text = mBuilder.getText();
if (TextUtils.isEmpty(text)) {
mBuilder.setError(getString(R.string.label_text_is_empty));
} else if (getString(R.string.default_download_label_name).equals(text)) {
mBuilder.setError(getString(R.string.label_text_is_invalid));
} else if (EhApplication.getDownloadManager(context).containLabel(text)) {
mBuilder.setError(getString(R.string.label_text_exist));
} else {
mBuilder.setError(null);
mDialog.dismiss();
EhApplication.getDownloadManager(context).renameLabel(mOriginalLabel, text);
if (mAdapter != null) {
mAdapter.notifyItemChanged(mPosition);
}
}
}
}
private clreplaced LabelHolder extends AbstractDraggableItemViewHolder implements View.OnClickListener {
public final TextView label;
public final View dragHandler;
public final View delete;
public LabelHolder(View itemView) {
super(itemView);
label = (TextView) ViewUtils.$$(itemView, R.id.label);
dragHandler = ViewUtils.$$(itemView, R.id.drag_handler);
delete = ViewUtils.$$(itemView, R.id.delete);
label.setOnClickListener(this);
delete.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int position = getAdapterPosition();
Context context = getContext2();
if (null == context || null == mList || null == mRecyclerView) {
return;
}
if (label == v) {
DownloadLabel raw = mList.get(position);
EditTextDialogBuilder builder = new EditTextDialogBuilder(context, raw.getLabel(), getString(R.string.download_labels));
builder.setreplacedle(R.string.rename_label_replacedle);
builder.setPositiveButton(android.R.string.ok, null);
AlertDialog dialog = builder.show();
new RenameLabelDialogHelper(builder, dialog, raw.getLabel(), position);
} else if (delete == v) {
final DownloadLabel label = mList.get(position);
new AlertDialog.Builder(context).setreplacedle(R.string.delete_label_replacedle).setMessage(getString(R.string.delete_label_message, label.getLabel())).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
EhApplication.getDownloadManager(context).deleteLabel(label.getLabel());
}
}).setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
if (null != mAdapter) {
mAdapter.notifyDataSetChanged();
}
updateView();
}
}).show();
}
}
}
private clreplaced LabelAdapter extends RecyclerView.Adapter<LabelHolder> implements DraggableItemAdapter<LabelHolder> {
private final LayoutInflater mInflater;
public LabelAdapter() {
mInflater = getLayoutInflater2();
replacedertUtils.replacedertNotNull(mInflater);
}
@Override
public LabelHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new LabelHolder(mInflater.inflate(R.layout.item_download_label, parent, false));
}
@Override
public void onBindViewHolder(LabelHolder holder, int position) {
if (mList != null) {
holder.label.setText(mList.get(position).getLabel());
}
}
@Override
public long gereplacedemId(int position) {
return mList != null ? mList.get(position).getId() : 0;
}
@Override
public int gereplacedemCount() {
return mList != null ? mList.size() : 0;
}
@Override
public boolean onCheckCanStartDrag(LabelHolder holder, int position, int x, int y) {
return ViewUtils.isViewUnder(holder.dragHandler, x, y, 0);
}
@Override
public ItemDraggableRange onGereplacedemDraggableRange(LabelHolder holder, int position) {
return null;
}
@Override
public void onMoveItem(int fromPosition, int toPosition) {
Context context = getContext2();
if (null == context || fromPosition == toPosition) {
return;
}
EhApplication.getDownloadManager(context).moveLabel(fromPosition, toPosition);
}
@Override
public boolean onCheckCanDrop(int draggingPosition, int dropPosition) {
return true;
}
@Override
public void onItemDragStarted(int position) {
}
@Override
public void onItemDragFinished(int fromPosition, int toPosition, boolean result) {
}
}
}
17
Source : HostsActivity.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
@Override
public boolean onItemClick(EasyRecyclerView easyRecyclerView, View view, int position, long id) {
Pair<String, String> pair = data.get(position);
Bundle args = new Bundle();
args.putString(KEY_HOST, pair.first);
args.putString(KEY_IP, pair.second);
DialogFragment fragment = new EditHostDialogFragment();
fragment.setArguments(args);
fragment.show(getSupportFragmentManager(), DIALOG_TAG_EDIT_HOST);
return true;
}
17
Source : GalleryCommentsScene.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
public final clreplaced GalleryCommentsScene extends ToolbarScene implements View.OnClickListener {
public static final String TAG = GalleryCommentsScene.clreplaced.getSimpleName();
public static final String KEY_API_UID = "api_uid";
public static final String KEY_API_KEY = "api_key";
public static final String KEY_GID = "gid";
public static final String KEY_TOKEN = "token";
public static final String KEY_COMMENT_LIST = "comment_list";
private static final int TYPE_COMMENT = 0;
private static final int TYPE_MORE = 1;
private static final int TYPE_PROGRESS = 2;
private long mApiUid;
private String mApiKey;
private long mGid;
private String mToken;
@Nullable
private GalleryCommentList mCommentList;
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private FabLayout mFabLayout;
@Nullable
private FloatingActionButton mFab;
@Nullable
private View mEditPanel;
@Nullable
private ImageView mSendImage;
@Nullable
private EditText mEditText;
@Nullable
private CommentAdapter mAdapter;
@Nullable
private ViewTransition mViewTransition;
private Drawable mSendDrawable;
private Drawable mPencilDrawable;
private long mCommentId;
private boolean mInAnimation = false;
private boolean mShowAllComments = false;
private boolean mRefreshingComments = false;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void handleArgs(Bundle args) {
if (args == null) {
return;
}
mApiUid = args.getLong(KEY_API_UID, -1L);
mApiKey = args.getString(KEY_API_KEY);
mGid = args.getLong(KEY_GID, -1L);
mToken = args.getString(KEY_TOKEN, null);
mCommentList = args.getParcelable(KEY_COMMENT_LIST);
mShowAllComments = mCommentList != null && !mCommentList.hasMore;
}
private void onInit() {
handleArgs(getArguments());
}
private void onRestore(@NonNull Bundle savedInstanceState) {
mApiUid = savedInstanceState.getLong(KEY_API_UID, -1L);
mApiKey = savedInstanceState.getString(KEY_API_KEY);
mGid = savedInstanceState.getLong(KEY_GID, -1L);
mToken = savedInstanceState.getString(KEY_TOKEN, null);
mCommentList = savedInstanceState.getParcelable(KEY_COMMENT_LIST);
mShowAllComments = mCommentList != null && !mCommentList.hasMore;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(KEY_API_UID, mApiUid);
outState.putString(KEY_API_KEY, mApiKey);
outState.putLong(KEY_GID, mGid);
outState.putString(KEY_TOKEN, mToken);
outState.putParcelable(KEY_COMMENT_LIST, mCommentList);
}
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_gallery_comments, container, false);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(view, R.id.recycler_view);
TextView tip = (TextView) ViewUtils.$$(view, R.id.tip);
mEditPanel = ViewUtils.$$(view, R.id.edit_panel);
mSendImage = (ImageView) ViewUtils.$$(mEditPanel, R.id.send);
mEditText = (EditText) ViewUtils.$$(mEditPanel, R.id.edit_text);
mFabLayout = (FabLayout) ViewUtils.$$(view, R.id.fab_layout);
mFab = (FloatingActionButton) ViewUtils.$$(view, R.id.fab);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
Resources resources = context.getResources();
int paddingBottomFab = resources.getDimensionPixelOffset(R.dimen.gallery_padding_bottom_fab);
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_sad_pandroid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
mSendDrawable = DrawableManager.getVectorDrawable(context, R.drawable.v_send_dark_x24);
mPencilDrawable = DrawableManager.getVectorDrawable(context, R.drawable.v_pencil_dark_x24);
mAdapter = new CommentAdapter();
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setShowLastDivider(true);
mRecyclerView.addItemDecoration(decoration);
// mRecyclerView.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
mRecyclerView.setHasFixedSize(true);
// mRecyclerView.setOnItemClickListener(this);
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), mRecyclerView.getPaddingBottom() + paddingBottomFab);
// Cancel change animator
RecyclerView.ItemAnimator itemAnimator = mRecyclerView.gereplacedemAnimator();
if (itemAnimator instanceof DefaulreplacedemAnimator) {
((DefaulreplacedemAnimator) itemAnimator).setSupportsChangeAnimations(false);
}
mSendImage.setOnClickListener(this);
mFab.setOnClickListener(this);
addAboveSnackView(mEditPanel);
addAboveSnackView(mFabLayout);
mViewTransition = new ViewTransition(mRecyclerView, tip);
updateView(false);
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
if (null != mEditPanel) {
removeAboveSnackView(mEditPanel);
mEditPanel = null;
}
if (null != mFabLayout) {
removeAboveSnackView(mFabLayout);
mFabLayout = null;
}
mFab = null;
mSendImage = null;
mEditText = null;
mAdapter = null;
mViewTransition = null;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.gallery_comments);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onNavigationClick() {
onBackPressed();
}
private void voteComment(long id, int vote) {
Context context = getContext2();
MainActivity activity = getActivity2();
if (null == context || null == activity) {
return;
}
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_VOTE_COMMENT).setArgs(mApiUid, mApiKey, mGid, mToken, id, vote).setCallback(new VoteCommentListener(context, activity.getStageId(), getTag()));
EhApplication.getEhClient(context).execute(request);
}
@SuppressLint("InflateParams")
public void showVoteStatusDialog(Context context, String voteStatus) {
String[] temp = StringUtils.split(voteStatus, ',');
final int length = temp.length;
final String[] userArray = new String[length];
final String[] voteArray = new String[length];
for (int i = 0; i < length; i++) {
String str = StringUtils.trim(temp[i]);
int index = str.lastIndexOf(' ');
if (index < 0) {
Log.d(TAG, "Something wrong happened about vote state");
userArray[i] = str;
voteArray[i] = "";
} else {
userArray[i] = StringUtils.trim(str.substring(0, index));
voteArray[i] = StringUtils.trim(str.substring(index + 1));
}
}
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
context = builder.getContext();
final LayoutInflater inflater = LayoutInflater.from(context);
EasyRecyclerView rv = (EasyRecyclerView) inflater.inflate(R.layout.dialog_recycler_view, null);
rv.setAdapter(new RecyclerView.Adapter<InfoHolder>() {
@Override
public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new InfoHolder(inflater.inflate(R.layout.item_drawer_favorites, parent, false));
}
@Override
public void onBindViewHolder(InfoHolder holder, int position) {
holder.key.setText(userArray[position]);
holder.value.setText(voteArray[position]);
}
@Override
public int gereplacedemCount() {
return length;
}
});
rv.setLayoutManager(new LinearLayoutManager(context));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setPadding(ResourcesUtils.getAttrDimensionPixelOffset(context, R.attr.dialogPreferredPadding));
rv.addItemDecoration(decoration);
// rv.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
rv.setClipToPadding(false);
builder.setView(rv).show();
}
private void showCommentDialog(int position) {
final Context context = getContext2();
if (context == null || mCommentList == null || mCommentList.comments == null || position >= mCommentList.comments.length || position < 0) {
return;
}
final GalleryComment comment = mCommentList.comments[position];
List<String> menu = new ArrayList<>();
final IntList menuId = new IntList();
Resources resources = context.getResources();
menu.add(resources.getString(R.string.copy_comment_text));
menuId.add(R.id.copy);
if (comment.editable) {
menu.add(resources.getString(R.string.edit_comment));
menuId.add(R.id.edit_comment);
}
if (comment.voteUpAble) {
menu.add(resources.getString(comment.voteUpEd ? R.string.cancel_vote_up : R.string.vote_up));
menuId.add(R.id.vote_up);
}
if (comment.voteDownAble) {
menu.add(resources.getString(comment.voteDownEd ? R.string.cancel_vote_down : R.string.vote_down));
menuId.add(R.id.vote_down);
}
if (!TextUtils.isEmpty(comment.voteState)) {
menu.add(resources.getString(R.string.check_vote_status));
menuId.add(R.id.check_vote_status);
}
new MaterialAlertDialogBuilder(context).sereplacedems(menu.toArray(new String[menu.size()]), (dialog, which) -> {
if (which < 0 || which >= menuId.size()) {
return;
}
int id = menuId.get(which);
switch(id) {
case R.id.copy:
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
cmb.setPrimaryClip(ClipData.newPlainText(null, comment.comment));
showTip(R.string.copied_to_clipboard, LENGTH_SHORT);
break;
case R.id.vote_up:
voteComment(comment.id, 1);
break;
case R.id.vote_down:
voteComment(comment.id, -1);
break;
case R.id.check_vote_status:
showVoteStatusDialog(context, comment.voteState);
break;
case R.id.edit_comment:
prepareEditComment(comment.id);
if (!mInAnimation && mEditPanel != null && mEditPanel.getVisibility() != View.VISIBLE) {
showEditPanel(true);
}
break;
}
}).show();
}
public boolean onItemClick(EasyRecyclerView parent, View view, int position) {
MainActivity activity = getActivity2();
if (null == activity) {
return false;
}
RecyclerView.ViewHolder holder = parent.getChildViewHolder(view);
if (holder instanceof ActualCommentHolder) {
ActualCommentHolder commentHolder = (ActualCommentHolder) holder;
ClickableSpan span = commentHolder.comment.getCurrentSpan();
commentHolder.comment.clearCurrentSpan();
if (span instanceof URLSpan) {
UrlOpener.openUrl(activity, ((URLSpan) span).getURL(), true);
} else {
showCommentDialog(position);
}
} else if (holder instanceof MoreCommentHolder && !mRefreshingComments && mAdapter != null) {
mRefreshingComments = true;
mShowAllComments = true;
mAdapter.notifyItemChanged(position);
String url = getGalleryDetailUrl();
if (url != null) {
// Request
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_GET_GALLERY_DETAIL).setArgs(url).setCallback(new RefreshCommentListener(activity, activity.getStageId(), getTag()));
EhApplication.getEhClient(activity).execute(request);
}
}
return true;
}
private void updateView(boolean animation) {
if (null == mViewTransition) {
return;
}
if (mCommentList == null || mCommentList.comments == null || mCommentList.comments.length <= 0) {
mViewTransition.showView(1, animation);
} else {
mViewTransition.showView(0, animation);
}
}
private void prepareNewComment() {
mCommentId = 0;
if (mSendImage != null) {
mSendImage.setImageDrawable(mSendDrawable);
}
}
private void prepareEditComment(long commentId) {
mCommentId = commentId;
if (mSendImage != null) {
mSendImage.setImageDrawable(mPencilDrawable);
}
}
private void showEditPanelWithAnimation() {
if (null == mFab || null == mEditPanel) {
return;
}
mInAnimation = true;
mFab.setTranslationX(0.0f);
mFab.setTranslationY(0.0f);
mFab.setScaleX(1.0f);
mFab.setScaleY(1.0f);
int fabEndX = mEditPanel.getLeft() + (mEditPanel.getWidth() / 2) - (mFab.getWidth() / 2);
int fabEndY = mEditPanel.getTop() + (mEditPanel.getHeight() / 2) - (mFab.getHeight() / 2);
mFab.animate().x(fabEndX).y(fabEndY).scaleX(0.0f).scaleY(0.0f).setInterpolator(AnimationUtils.SLOW_FAST_SLOW_INTERPOLATOR).setDuration(300L).setListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
if (null == mFab || null == mEditPanel) {
return;
}
((View) mFab).setVisibility(View.INVISIBLE);
mEditPanel.setVisibility(View.VISIBLE);
int halfW = mEditPanel.getWidth() / 2;
int halfH = mEditPanel.getHeight() / 2;
Animator animator = ViewAnimationUtils.createCircularReveal(mEditPanel, halfW, halfH, 0, (float) Math.hypot(halfW, halfH)).setDuration(300L);
animator.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator a) {
mInAnimation = false;
}
});
animator.start();
}
}).start();
}
private void showEditPanel(boolean animation) {
if (animation) {
showEditPanelWithAnimation();
} else {
if (null == mFab || null == mEditPanel) {
return;
}
((View) mFab).setVisibility(View.INVISIBLE);
mEditPanel.setVisibility(View.VISIBLE);
}
}
private void hideEditPanelWithAnimation() {
if (null == mFab || null == mEditPanel) {
return;
}
mInAnimation = true;
int halfW = mEditPanel.getWidth() / 2;
int halfH = mEditPanel.getHeight() / 2;
Animator animator = ViewAnimationUtils.createCircularReveal(mEditPanel, halfW, halfH, (float) Math.hypot(halfW, halfH), 0.0f).setDuration(300L);
animator.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator a) {
if (null == mFab || null == mEditPanel) {
return;
}
if (Looper.myLooper() != Looper.getMainLooper()) {
// Some devices may run this block in non-UI thread.
// It might be a bug of Android OS.
// Check it here to avoid crash.
return;
}
mEditPanel.setVisibility(View.GONE);
((View) mFab).setVisibility(View.VISIBLE);
int fabStartX = mEditPanel.getLeft() + (mEditPanel.getWidth() / 2) - (mFab.getWidth() / 2);
int fabStartY = mEditPanel.getTop() + (mEditPanel.getHeight() / 2) - (mFab.getHeight() / 2);
mFab.setX(fabStartX);
mFab.setY(fabStartY);
mFab.setScaleX(0.0f);
mFab.setScaleY(0.0f);
mFab.setRotation(-45.0f);
mFab.animate().translationX(0.0f).translationY(0.0f).scaleX(1.0f).scaleY(1.0f).rotation(0.0f).setInterpolator(AnimationUtils.SLOW_FAST_SLOW_INTERPOLATOR).setDuration(300L).setListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
mInAnimation = false;
}
}).start();
}
});
animator.start();
}
private void hideEditPanel(boolean animation) {
if (animation) {
hideEditPanelWithAnimation();
} else {
if (null == mFab || null == mEditPanel) {
return;
}
((View) mFab).setVisibility(View.VISIBLE);
mEditPanel.setVisibility(View.INVISIBLE);
}
}
@Nullable
private String getGalleryDetailUrl() {
if (mGid != -1 && mToken != null) {
return EhUrl.getGalleryDetailUrl(mGid, mToken, 0, mShowAllComments);
} else {
return null;
}
}
@Override
public void onClick(View v) {
Context context = getContext2();
MainActivity activity = getActivity2();
if (null == context || null == activity || null == mEditText) {
return;
}
if (mFab == v) {
if (!mInAnimation) {
prepareNewComment();
showEditPanel(true);
}
} else if (mSendImage == v) {
if (!mInAnimation) {
String comment = mEditText.getText().toString();
if (TextUtils.isEmpty(comment)) {
// Comment is empty
return;
}
String url = getGalleryDetailUrl();
if (url == null) {
return;
}
// Request
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_GET_COMMENT_GALLERY).setArgs(url, comment, mCommentId != 0 ? Long.toString(mCommentId) : null).setCallback(new CommentGalleryListener(context, activity.getStageId(), getTag(), mCommentId));
EhApplication.getEhClient(context).execute(request);
hideSoftInput();
hideEditPanel(true);
}
}
}
@Override
public void onBackPressed() {
if (mInAnimation) {
return;
}
if (null != mEditPanel && mEditPanel.getVisibility() == View.VISIBLE) {
hideEditPanel(true);
} else {
finish();
}
}
private void onRefreshGallerySuccess(GalleryCommentList result) {
if (mAdapter == null) {
return;
}
mRefreshingComments = false;
mCommentList = result;
mAdapter.notifyDataSetChanged();
updateView(true);
Bundle re = new Bundle();
re.putParcelable(KEY_COMMENT_LIST, result);
setResult(SceneFragment.RESULT_OK, re);
}
private void onRefreshGalleryFailure() {
if (mAdapter == null) {
return;
}
mRefreshingComments = false;
int position = mAdapter.gereplacedemCount() - 1;
if (position >= 0) {
mAdapter.notifyItemChanged(position);
}
}
private void onCommentGallerySuccess(GalleryCommentList result) {
if (mAdapter == null) {
return;
}
mCommentList = result;
mAdapter.notifyDataSetChanged();
Bundle re = new Bundle();
re.putParcelable(KEY_COMMENT_LIST, result);
setResult(SceneFragment.RESULT_OK, re);
// Remove text
if (mEditText != null) {
mEditText.setText("");
}
updateView(true);
}
private void onVoteCommentSuccess(VoteCommentParser.Result result) {
if (mAdapter == null || mCommentList == null || mCommentList.comments == null) {
return;
}
int position = -1;
for (int i = 0, n = mCommentList.comments.length; i < n; i++) {
GalleryComment comment = mCommentList.comments[i];
if (comment.id == result.id) {
position = i;
break;
}
}
if (-1 == position) {
Log.d(TAG, "Can't find comment with id " + result.id);
return;
}
// Update comment
GalleryComment comment = mCommentList.comments[position];
comment.score = result.score;
if (result.expectVote > 0) {
comment.voteUpEd = 0 != result.vote;
comment.voteDownEd = false;
} else {
comment.voteDownEd = 0 != result.vote;
comment.voteUpEd = false;
}
mAdapter.notifyItemChanged(position);
Bundle re = new Bundle();
re.putParcelable(KEY_COMMENT_LIST, mCommentList);
setResult(SceneFragment.RESULT_OK, re);
}
private static clreplaced RefreshCommentListener extends EhCallback<GalleryCommentsScene, GalleryDetail> {
public RefreshCommentListener(Context context, int stageId, String sceneTag) {
super(context, stageId, sceneTag);
}
@Override
public void onSuccess(GalleryDetail result) {
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onRefreshGallerySuccess(result.comments);
}
}
@Override
public void onFailure(Exception e) {
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onRefreshGalleryFailure();
}
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryCommentsScene;
}
}
private static clreplaced CommentGalleryListener extends EhCallback<GalleryCommentsScene, GalleryCommentList> {
private final long mCommentId;
public CommentGalleryListener(Context context, int stageId, String sceneTag, long commentId) {
super(context, stageId, sceneTag);
mCommentId = commentId;
}
@Override
public void onSuccess(GalleryCommentList result) {
showTip(mCommentId != 0 ? R.string.edit_comment_successfully : R.string.comment_successfully, LENGTH_SHORT);
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onCommentGallerySuccess(result);
}
}
@Override
public void onFailure(Exception e) {
showTip(getContent().getString(mCommentId != 0 ? R.string.edit_comment_failed : R.string.comment_failed) + "\n" + ExceptionUtils.getReadableString(e), LENGTH_LONG);
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryCommentsScene;
}
}
private static clreplaced VoteCommentListener extends EhCallback<GalleryCommentsScene, VoteCommentParser.Result> {
public VoteCommentListener(Context context, int stageId, String sceneTag) {
super(context, stageId, sceneTag);
}
@Override
public void onSuccess(VoteCommentParser.Result result) {
showTip(result.expectVote > 0 ? (0 != result.vote ? R.string.vote_up_successfully : R.string.cancel_vote_up_successfully) : (0 != result.vote ? R.string.vote_down_successfully : R.string.cancel_vote_down_successfully), LENGTH_SHORT);
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onVoteCommentSuccess(result);
}
}
@Override
public void onFailure(Exception e) {
showTip(R.string.vote_failed, LENGTH_LONG);
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryCommentsScene;
}
}
private clreplaced 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 abstract clreplaced CommentHolder extends RecyclerView.ViewHolder {
public CommentHolder(LayoutInflater inflater, int resId, ViewGroup parent) {
super(inflater.inflate(resId, parent, false));
}
}
private clreplaced ActualCommentHolder extends CommentHolder {
private final TextView user;
private final TextView time;
private final LinkifyTextView comment;
public ActualCommentHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater, R.layout.item_gallery_comment, parent);
user = itemView.findViewById(R.id.user);
time = itemView.findViewById(R.id.time);
comment = itemView.findViewById(R.id.comment);
}
private CharSequence generateComment(Context context, ObservedTextView textView, GalleryComment comment) {
SpannableStringBuilder ssb = Html.fromHtml(comment.comment, new URLImageGetter(textView, EhApplication.getConaco(context)), null);
if (0 != comment.id && 0 != comment.score) {
int score = comment.score;
String scoreString = score > 0 ? "+" + score : Integer.toString(score);
SpannableString ss = new SpannableString(scoreString);
ss.setSpan(new RelativeSizeSpan(0.8f), 0, scoreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new StyleSpan(Typeface.BOLD), 0, scoreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new ForegroundColorSpan(AttrResources.getAttrColor(context, android.R.attr.textColorSecondary)), 0, scoreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append(" ").append(ss);
}
if (comment.lastEdited != 0) {
String str = context.getString(R.string.last_edited, ReadableTime.getTimeAgo(comment.lastEdited));
SpannableString ss = new SpannableString(str);
ss.setSpan(new RelativeSizeSpan(0.8f), 0, str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new StyleSpan(Typeface.BOLD), 0, str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new ForegroundColorSpan(AttrResources.getAttrColor(context, android.R.attr.textColorSecondary)), 0, str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append("\n\n").append(ss);
}
return TextUrl.handleTextUrl(ssb);
}
public void bind(GalleryComment value) {
user.setText(value.user);
time.setText(ReadableTime.getTimeAgo(value.time));
comment.setText(generateComment(comment.getContext(), comment, value));
}
}
private clreplaced MoreCommentHolder extends CommentHolder {
public MoreCommentHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater, R.layout.item_gallery_comment_more, parent);
}
}
private clreplaced ProgressCommentHolder extends CommentHolder {
public ProgressCommentHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater, R.layout.item_gallery_comment_progress, parent);
}
}
private clreplaced CommentAdapter extends RecyclerView.Adapter<CommentHolder> {
private final LayoutInflater mInflater;
public CommentAdapter() {
mInflater = getLayoutInflater2();
replacedertUtils.replacedertNotNull(mInflater);
}
@Override
public CommentHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
switch(viewType) {
case TYPE_COMMENT:
return new ActualCommentHolder(mInflater, parent);
case TYPE_MORE:
return new MoreCommentHolder(mInflater, parent);
case TYPE_PROGRESS:
return new ProgressCommentHolder(mInflater, parent);
default:
throw new IllegalStateException("Invalid view type: " + viewType);
}
}
@Override
public void onBindViewHolder(@NonNull CommentHolder holder, int position) {
Context context = getContext2();
if (context == null || mCommentList == null) {
return;
}
holder.itemView.setOnClickListener(v -> onItemClick(mRecyclerView, holder.itemView, position));
holder.itemView.setClickable(true);
holder.itemView.setFocusable(true);
if (holder instanceof ActualCommentHolder) {
((ActualCommentHolder) holder).bind(mCommentList.comments[position]);
}
}
@Override
public int gereplacedemCount() {
if (mCommentList == null || mCommentList.comments == null) {
return 0;
} else if (mCommentList.hasMore) {
return mCommentList.comments.length + 1;
} else {
return mCommentList.comments.length;
}
}
@Override
public int gereplacedemViewType(int position) {
if (position >= mCommentList.comments.length) {
return mRefreshingComments ? TYPE_PROGRESS : TYPE_MORE;
} else {
return TYPE_COMMENT;
}
}
}
}
17
Source : GalleryCommentsScene.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
@SuppressLint("InflateParams")
public void showVoteStatusDialog(Context context, String voteStatus) {
String[] temp = StringUtils.split(voteStatus, ',');
final int length = temp.length;
final String[] userArray = new String[length];
final String[] voteArray = new String[length];
for (int i = 0; i < length; i++) {
String str = StringUtils.trim(temp[i]);
int index = str.lastIndexOf(' ');
if (index < 0) {
Log.d(TAG, "Something wrong happened about vote state");
userArray[i] = str;
voteArray[i] = "";
} else {
userArray[i] = StringUtils.trim(str.substring(0, index));
voteArray[i] = StringUtils.trim(str.substring(index + 1));
}
}
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
context = builder.getContext();
final LayoutInflater inflater = LayoutInflater.from(context);
EasyRecyclerView rv = (EasyRecyclerView) inflater.inflate(R.layout.dialog_recycler_view, null);
rv.setAdapter(new RecyclerView.Adapter<InfoHolder>() {
@Override
public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new InfoHolder(inflater.inflate(R.layout.item_drawer_favorites, parent, false));
}
@Override
public void onBindViewHolder(InfoHolder holder, int position) {
holder.key.setText(userArray[position]);
holder.value.setText(voteArray[position]);
}
@Override
public int gereplacedemCount() {
return length;
}
});
rv.setLayoutManager(new LinearLayoutManager(context));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setPadding(ResourcesUtils.getAttrDimensionPixelOffset(context, R.attr.dialogPreferredPadding));
rv.addItemDecoration(decoration);
// rv.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
rv.setClipToPadding(false);
builder.setView(rv).show();
}
17
Source : GalleryPreviewsScene.java
with Apache License 2.0
from duzhaokun123
with Apache License 2.0
from duzhaokun123
public clreplaced GalleryPreviewsScene extends ToolbarScene {
public static final String KEY_GALLERY_INFO = "gallery_info";
private final static String KEY_HAS_FIRST_REFRESH = "has_first_refresh";
/*---------------
Whole life cycle
---------------*/
@Nullable
private EhClient mClient;
@Nullable
private GalleryInfo mGalleryInfo;
/*---------------
View life cycle
---------------*/
@Nullable
private ContentLayout mContentLayout;
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private GalleryPreviewAdapter mAdapter;
@Nullable
private GalleryPreviewHelper mHelper;
private boolean mHasFirstRefresh = false;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = getContext();
replacedertUtils.replacedertNotNull(context);
mClient = EhApplication.getEhClient(context);
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void onInit() {
Bundle args = getArguments();
if (args == null) {
return;
}
mGalleryInfo = args.getParcelable(KEY_GALLERY_INFO);
}
private void onRestore(@NonNull Bundle savedInstanceState) {
mGalleryInfo = savedInstanceState.getParcelable(KEY_GALLERY_INFO);
mHasFirstRefresh = savedInstanceState.getBoolean(KEY_HAS_FIRST_REFRESH);
}
@Override
public void onSaveInstanceState(@NonNull 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_GALLERY_INFO, mGalleryInfo);
}
@Nullable
@Override
public View onCreateViewWithToolbar(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mContentLayout = (ContentLayout) inflater.inflate(R.layout.scene_gallery_previews, container, false);
mContentLayout.hideFastScroll();
mRecyclerView = mContentLayout.getRecyclerView();
Context context = getContext();
replacedertUtils.replacedertNotNull(context);
Resources resources = context.getResources();
mAdapter = new GalleryPreviewAdapter();
mRecyclerView.setAdapter(mAdapter);
int columnWidth = resources.getDimensionPixelOffset(Settings.getThumbSizeResId());
AutoGridLayoutManager layoutManager = new AutoGridLayoutManager(context, columnWidth);
layoutManager.setStrategy(AutoGridLayoutManager.STRATEGY_SUITABLE_SIZE);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setClipToPadding(false);
int padding = LayoutUtils.dp2pix(context, 4);
MarginItemDecoration decoration = new MarginItemDecoration(padding, padding, padding, padding, padding);
mRecyclerView.addItemDecoration(decoration);
decoration.applyPaddings(mRecyclerView);
mHelper = new GalleryPreviewHelper();
mContentLayout.setHelper(mHelper);
// Only refresh for the first time
if (!mHasFirstRefresh) {
mHasFirstRefresh = true;
mHelper.firstRefresh();
}
return mContentLayout;
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mHelper) {
if (1 == mHelper.getShownViewIndex()) {
mHasFirstRefresh = false;
}
}
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
mAdapter = null;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.gallery_previews);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public int getMenuResId() {
return R.menu.scene_gallery_previews;
}
@Override
public boolean onMenuItemClick(MenuItem item) {
Context context = getContext();
if (null == context) {
return false;
}
int id = item.gereplacedemId();
if (id == R.id.action_go_to) {
if (mHelper == null) {
return true;
}
int pages = mHelper.getPages();
if (pages > 0 && mHelper.canGoTo()) {
GoToDialogHelper helper = new GoToDialogHelper(pages, mHelper.getPageForTop());
AlertDialog dialog = new MaterialAlertDialogBuilder(context).setreplacedle(R.string.go_to).setView(R.layout.dialog_go_to).setPositiveButton(android.R.string.ok, null).create();
dialog.show();
helper.setDialog(dialog);
}
return true;
}
return false;
}
@Override
public void onNavigationClick() {
onBackPressed();
}
public boolean onItemClick(int position) {
Context context = getContext();
if (null != context && null != mHelper && null != mGalleryInfo) {
GalleryPreview p = mHelper.getDataAtEx(position);
if (p != null) {
Intent intent = new Intent(context, GalleryActivity.clreplaced);
intent.setAction(GalleryActivity.ACTION_EH);
intent.putExtra(GalleryActivity.KEY_GALLERY_INFO, mGalleryInfo);
intent.putExtra(GalleryActivity.KEY_PAGE, p.getPosition());
startActivity(intent);
}
}
return true;
}
private void onGetPreviewSetSuccess(Pair<PreviewSet, Integer> result, int taskId) {
if (null != mHelper && mHelper.isCurrentTask(taskId) && null != mGalleryInfo) {
PreviewSet previewSet = result.first;
int size = previewSet.size();
ArrayList<GalleryPreview> list = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
list.add(previewSet.getGalleryPreview(mGalleryInfo.gid, i));
}
mHelper.onGetPageData(taskId, result.second, 0, list);
}
}
private void onGetPreviewSetFailure(Exception e, int taskId) {
if (mHelper != null && mHelper.isCurrentTask(taskId)) {
mHelper.onGetException(taskId, e);
}
}
private static clreplaced GetPreviewSetListener extends EhCallback<GalleryPreviewsScene, Pair<PreviewSet, Integer>> {
private final int mTaskId;
public GetPreviewSetListener(Context context, int stageId, String sceneTag, int taskId) {
super(context, stageId, sceneTag);
mTaskId = taskId;
}
@Override
public void onSuccess(Pair<PreviewSet, Integer> result) {
GalleryPreviewsScene scene = getScene();
if (scene != null) {
scene.onGetPreviewSetSuccess(result, mTaskId);
}
}
@Override
public void onFailure(Exception e) {
GalleryPreviewsScene scene = getScene();
if (scene != null) {
scene.onGetPreviewSetFailure(e, mTaskId);
}
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryPreviewsScene;
}
}
private static clreplaced GalleryPreviewHolder extends RecyclerView.ViewHolder {
public LoadImageView image;
public TextView text;
public GalleryPreviewHolder(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.image);
text = itemView.findViewById(R.id.text);
}
}
private clreplaced GalleryPreviewAdapter extends RecyclerView.Adapter<GalleryPreviewHolder> {
private final LayoutInflater mInflater;
public GalleryPreviewAdapter() {
mInflater = getLayoutInflater();
replacedertUtils.replacedertNotNull(mInflater);
}
@NonNull
@Override
public GalleryPreviewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new GalleryPreviewHolder(mInflater.inflate(R.layout.item_gallery_preview, parent, false));
}
@Override
@SuppressLint("SetTextI18n")
public void onBindViewHolder(@NonNull GalleryPreviewHolder holder, int position) {
if (null != mHelper) {
GalleryPreview preview = mHelper.getDataAtEx(position);
if (preview != null) {
preview.load(holder.image);
holder.text.setText(Integer.toString(preview.getPosition() + 1));
}
}
holder.itemView.setOnClickListener(v -> onItemClick(position));
}
@Override
public int gereplacedemCount() {
return mHelper != null ? mHelper.size() : 0;
}
}
private clreplaced GalleryPreviewHelper extends ContentLayout.ContentHelper<GalleryPreview> {
@Override
protected void getPageData(final int taskId, int type, int page) {
MainActivity activity = getMainActivity();
if (null == activity || null == mClient || null == mGalleryInfo) {
onGetException(taskId, new EhException(getString(R.string.error_cannot_find_gallery)));
return;
}
String url = EhUrl.getGalleryDetailUrl(mGalleryInfo.gid, mGalleryInfo.token, page, false);
EhRequest request = new EhRequest();
request.setMethod(EhClient.METHOD_GET_PREVIEW_SET);
request.setCallback(new GetPreviewSetListener(getContext(), activity.getStageId(), getTag(), taskId));
request.setArgs(url);
mClient.execute(request);
}
@Override
protected Context getContext() {
return GalleryPreviewsScene.this.getContext();
}
@Override
protected void notifyDataSetChanged() {
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
protected boolean isDuplicate(GalleryPreview d1, GalleryPreview d2) {
return false;
}
}
private clreplaced GoToDialogHelper implements View.OnClickListener, DialogInterface.OnDismissListener {
private final int mPages;
private final int mCurrentPage;
@Nullable
private Slider mSlider;
@Nullable
private Dialog mDialog;
private GoToDialogHelper(int pages, int currentPage) {
mPages = pages;
mCurrentPage = currentPage;
}
public void setDialog(@NonNull AlertDialog dialog) {
mDialog = dialog;
((TextView) ViewUtils.$$(dialog, R.id.start)).setText(String.format(Locale.US, "%d", 1));
((TextView) ViewUtils.$$(dialog, R.id.end)).setText(String.format(Locale.US, "%d", mPages));
mSlider = (Slider) ViewUtils.$$(dialog, R.id.slider);
mSlider.setRange(1, mPages);
mSlider.setProgress(mCurrentPage + 1);
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(this);
dialog.setOnDismissListener(this);
}
@Override
public void onClick(View v) {
if (null == mSlider) {
return;
}
int page = mSlider.getProgress() - 1;
if (page >= 0 && page < mPages && mHelper != null) {
mHelper.goTo(page);
if (mDialog != null) {
mDialog.dismiss();
mDialog = null;
}
} else {
showTip(R.string.error_out_of_range, LENGTH_LONG);
}
}
@Override
public void onDismiss(DialogInterface dialog) {
mDialog = null;
mSlider = null;
}
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime());
v.setPadding(insets1.left, 0, insets1.right, 0);
View statusBarBackground = v.findViewById(R.id.status_bar_background);
statusBarBackground.getLayoutParams().height = insets1.top;
statusBarBackground.setBackgroundColor(AttrResources.getAttrColor(requireContext(), R.attr.colorPrimaryDark));
if (mContentLayout != null) {
mContentLayout.setFitPaddingBottom(insets1.bottom);
}
return WindowInsetsCompat.CONSUMED;
}
}
16
Source : HistoryScene.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
public clreplaced HistoryScene extends ToolbarScene {
/*---------------
View life cycle
---------------*/
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private ViewTransition mViewTransition;
@Nullable
private RecyclerView.Adapter<?> mAdapter;
@Nullable
private LazyList<HistoryInfo> mLazyList;
private DownloadManager mDownloadManager;
private DownloadManager.DownloadInfoListener mDownloadInfoListener;
private FavouriteStatusRouter mFavouriteStatusRouter;
private FavouriteStatusRouter.Listener mFavouriteStatusRouterListener;
@Override
public void onDestroy() {
super.onDestroy();
mDownloadManager.removeDownloadInfoListener(mDownloadInfoListener);
mFavouriteStatusRouter.removeListener(mFavouriteStatusRouterListener);
}
@Override
public int getNavCheckedItem() {
return R.id.nav_history;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = getContext2();
replacedert context != null;
mDownloadManager = EhApplication.getDownloadManager(context);
mDownloadManager = EhApplication.getDownloadManager(context);
mFavouriteStatusRouter = EhApplication.getFavouriteStatusRouter(context);
mDownloadInfoListener = new DownloadManager.DownloadInfoListener() {
@Override
public void onAdd(@NonNull DownloadInfo info, @NonNull List<DownloadInfo> list, int position) {
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
}
@Override
public void onUpdate(@NonNull DownloadInfo info, @NonNull List<DownloadInfo> list) {
}
@Override
public void onUpdateAll() {
}
@Override
public void onReload() {
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
}
@Override
public void onChange() {
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
}
@Override
public void onRenameLabel(String from, String to) {
}
@Override
public void onRemove(@NonNull DownloadInfo info, @NonNull List<DownloadInfo> list, int position) {
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
}
@Override
public void onUpdateLabels() {
}
};
mDownloadManager.addDownloadInfoListener(mDownloadInfoListener);
mFavouriteStatusRouterListener = (gid, slot) -> {
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
};
mFavouriteStatusRouter.addListener(mFavouriteStatusRouterListener);
}
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_history, container, false);
View content = ViewUtils.$$(view, R.id.content);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(content, R.id.recycler_view);
FastScroller fastScroller = (FastScroller) ViewUtils.$$(content, R.id.fast_scroller);
TextView tip = (TextView) ViewUtils.$$(view, R.id.tip);
mViewTransition = new ViewTransition(content, tip);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
Resources resources = context.getResources();
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_history);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
RecyclerViewTouchActionGuardManager guardManager = new RecyclerViewTouchActionGuardManager();
guardManager.setInterceptVerticalScrollingWhileAnimationRunning(true);
guardManager.setEnabled(true);
RecyclerViewSwipeManager swipeManager = new RecyclerViewSwipeManager();
mAdapter = new HistoryAdapter();
mAdapter.setHreplacedtableIds(true);
mAdapter = swipeManager.createWrappedAdapter(mAdapter);
mRecyclerView.setAdapter(mAdapter);
final GeneralItemAnimator animator = new SwipeDismissItemAnimator();
animator.setSupportsChangeAnimations(false);
mRecyclerView.sereplacedemAnimator(animator);
AutoStaggeredGridLayoutManager layoutManager = new AutoStaggeredGridLayoutManager(0, StaggeredGridLayoutManager.VERTICAL);
layoutManager.setColumnSize(resources.getDimensionPixelOffset(Settings.getDetailSizeResId()));
layoutManager.setStrategy(AutoStaggeredGridLayoutManager.STRATEGY_MIN_SIZE);
mRecyclerView.setLayoutManager(layoutManager);
// mRecyclerView.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
// mRecyclerView.setDrawSelectorOnTop(true);
mRecyclerView.setClipToPadding(false);
mRecyclerView.setClipChildren(false);
// mRecyclerView.setOnItemClickListener(this);
// mRecyclerView.setOnItemLongClickListener(this);
int interval = resources.getDimensionPixelOffset(R.dimen.gallery_list_interval);
int paddingH = resources.getDimensionPixelOffset(R.dimen.gallery_list_margin_h);
int paddingV = resources.getDimensionPixelOffset(R.dimen.gallery_list_margin_v);
MarginItemDecoration decoration = new MarginItemDecoration(interval, paddingH, paddingV, paddingH, paddingV);
mRecyclerView.addItemDecoration(decoration);
decoration.applyPaddings(mRecyclerView);
guardManager.attachRecyclerView(mRecyclerView);
swipeManager.attachRecyclerView(mRecyclerView);
fastScroller.attachToRecyclerView(mRecyclerView);
HandlerDrawable handlerDrawable = new HandlerDrawable();
handlerDrawable.setColor(AttrResources.getAttrColor(context, R.attr.widgetColorThemeAccent));
fastScroller.setHandlerDrawable(handlerDrawable);
updateLazyList();
updateView(false);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.history);
setNavigationIcon(new DrawerArrowDrawable(getContext2(), Color.WHITE));
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mLazyList) {
mLazyList.close();
mLazyList = null;
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
}
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
mViewTransition = null;
mAdapter = null;
}
// Remember to notify
private void updateLazyList() {
LazyList<HistoryInfo> lazyList = EhDB.getHistoryLazyList();
if (mLazyList != null) {
mLazyList.close();
}
mLazyList = lazyList;
}
private void updateView(boolean animation) {
if (null == mAdapter || null == mViewTransition) {
return;
}
if (mAdapter.gereplacedemCount() == 0) {
mViewTransition.showView(1, animation);
} else {
mViewTransition.showView(0, animation);
}
}
@Override
public void onNavigationClick() {
toggleDrawer(Gravity.LEFT);
}
@Override
public int getMenuResId() {
return R.menu.scene_history;
}
private void showClearAllDialog() {
new MaterialAlertDialogBuilder(getContext2()).setMessage(R.string.clear_all_history).setPositiveButton(R.string.clear_all, (dialog, which) -> {
if (DialogInterface.BUTTON_POSITIVE != which || null == mAdapter) {
return;
}
EhDB.clearHistoryInfo();
updateLazyList();
mAdapter.notifyDataSetChanged();
updateView(true);
}).show();
}
@Override
public boolean onMenuItemClick(MenuItem item) {
// Skip when in choice mode
Context context = getContext2();
if (null == context) {
return false;
}
int id = item.gereplacedemId();
switch(id) {
case R.id.action_clear_all:
{
showClearAllDialog();
return true;
}
}
return false;
}
public boolean onItemClick(View view, int position) {
if (null == mLazyList) {
return false;
}
Bundle args = new Bundle();
args.putString(GalleryDetailScene.KEY_ACTION, GalleryDetailScene.ACTION_GALLERY_INFO);
args.putParcelable(GalleryDetailScene.KEY_GALLERY_INFO, mLazyList.get(position));
Announcer announcer = new Announcer(GalleryDetailScene.clreplaced).setArgs(args);
View thumb;
if (null != (thumb = view.findViewById(R.id.thumb))) {
announcer.setTranHelper(new EnterGalleryDetailTransaction(thumb));
}
startScene(announcer);
return true;
}
public boolean onItemLongClick(int position) {
final Context context = getContext2();
final MainActivity activity = getActivity2();
if (null == context || null == activity || null == mLazyList) {
return false;
}
final GalleryInfo gi = mLazyList.get(position);
if (gi == null) {
return true;
}
boolean downloaded = mDownloadManager.getDownloadState(gi.gid) != DownloadInfo.STATE_INVALID;
boolean favourited = gi.favoriteSlot != -2;
CharSequence[] items = downloaded ? new CharSequence[] { context.getString(R.string.read), context.getString(R.string.delete_downloads), context.getString(favourited ? R.string.remove_from_favourites : R.string.add_to_favourites), context.getString(R.string.delete), context.getString(R.string.download_move_dialog_replacedle) } : new CharSequence[] { context.getString(R.string.read), context.getString(R.string.download), context.getString(favourited ? R.string.remove_from_favourites : R.string.add_to_favourites), context.getString(R.string.delete) };
int[] icons = downloaded ? new int[] { R.drawable.v_book_open_x24, R.drawable.v_delete_x24, favourited ? R.drawable.v_heart_broken_x24 : R.drawable.v_heart_x24, R.drawable.v_delete_x24, R.drawable.v_folder_move_x24 } : new int[] { R.drawable.v_book_open_x24, R.drawable.v_download_x24, favourited ? R.drawable.v_heart_broken_x24 : R.drawable.v_heart_x24, R.drawable.v_delete_x24 };
new MaterialAlertDialogBuilder(context).setreplacedle(EhUtils.getSuitablereplacedle(gi)).setAdapter(new SelecreplacedemWithIconAdapter(context, items, icons), (dialog, which) -> {
switch(which) {
case // Read
0:
Intent intent = new Intent(activity, GalleryActivity.clreplaced);
intent.setAction(GalleryActivity.ACTION_EH);
intent.putExtra(GalleryActivity.KEY_GALLERY_INFO, gi);
startActivity(intent);
break;
case // Download
1:
if (downloaded) {
new MaterialAlertDialogBuilder(context).setreplacedle(R.string.download_remove_dialog_replacedle).setMessage(getString(R.string.download_remove_dialog_message, gi.replacedle)).setPositiveButton(android.R.string.ok, (dialog1, which1) -> mDownloadManager.deleteDownload(gi.gid)).show();
} else {
CommonOperations.startDownload(activity, gi, false);
}
break;
case // Favorites
2:
if (favourited) {
CommonOperations.removeFromFavorites(activity, gi, new RemoveFromFavoriteListener(context, activity.getStageId(), getTag()));
} else {
CommonOperations.addToFavorites(activity, gi, new AddToFavoriteListener(context, activity.getStageId(), getTag()));
}
break;
case // Delete
3:
if (null == mLazyList || null == mAdapter) {
return;
}
HistoryInfo info = mLazyList.get(position);
EhDB.deleteHistoryInfo(info);
updateLazyList();
mAdapter.notifyDataSetChanged();
updateView(true);
break;
case // Move
4:
List<DownloadLabel> labelRawList = EhApplication.getDownloadManager(context).getLabelList();
List<String> labelList = new ArrayList<>(labelRawList.size() + 1);
labelList.add(getString(R.string.default_download_label_name));
for (int i = 0, n = labelRawList.size(); i < n; i++) {
labelList.add(labelRawList.get(i).getLabel());
}
String[] labels = labelList.toArray(new String[0]);
MoveDialogHelper helper = new MoveDialogHelper(labels, gi);
new MaterialAlertDialogBuilder(context).setreplacedle(R.string.download_move_dialog_replacedle).sereplacedems(labels, helper).show();
break;
}
}).show();
return true;
}
private clreplaced MoveDialogHelper implements DialogInterface.OnClickListener {
private final String[] mLabels;
private final GalleryInfo mGi;
public MoveDialogHelper(String[] labels, GalleryInfo gi) {
mLabels = labels;
mGi = gi;
}
@Override
public void onClick(DialogInterface dialog, int which) {
// Cancel check mode
Context context = getContext2();
if (null == context) {
return;
}
if (null != mRecyclerView) {
mRecyclerView.outOfCustomChoiceMode();
}
DownloadManager downloadManager = EhApplication.getDownloadManager(context);
DownloadInfo downloadInfo = downloadManager.getDownloadInfo(mGi.gid);
if (downloadInfo == null) {
return;
}
String label = which == 0 ? null : mLabels[which];
downloadManager.changeLabel(Collections.singletonList(downloadInfo), label);
}
}
private static clreplaced AddToFavoriteListener extends EhCallback<GalleryListScene, Void> {
public AddToFavoriteListener(Context context, int stageId, String sceneTag) {
super(context, stageId, sceneTag);
}
@Override
public void onSuccess(Void result) {
showTip(R.string.add_to_favorite_success, LENGTH_SHORT);
}
@Override
public void onFailure(Exception e) {
showTip(R.string.add_to_favorite_failure, LENGTH_LONG);
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryListScene;
}
}
private static clreplaced RemoveFromFavoriteListener extends EhCallback<GalleryListScene, Void> {
public RemoveFromFavoriteListener(Context context, int stageId, String sceneTag) {
super(context, stageId, sceneTag);
}
@Override
public void onSuccess(Void result) {
showTip(R.string.remove_from_favorite_success, LENGTH_SHORT);
}
@Override
public void onFailure(Exception e) {
showTip(R.string.remove_from_favorite_failure, LENGTH_LONG);
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryListScene;
}
}
private static clreplaced HistoryHolder extends AbstractSwipeableItemViewHolder {
public final View card;
public final LoadImageView thumb;
public final TextView replacedle;
public final TextView uploader;
public final SimpleRatingView rating;
public final TextView category;
public final TextView posted;
public final TextView simpleLanguage;
public HistoryHolder(View itemView) {
super(itemView);
card = itemView.findViewById(R.id.card);
thumb = itemView.findViewById(R.id.thumb);
replacedle = itemView.findViewById(R.id.replacedle);
uploader = itemView.findViewById(R.id.uploader);
rating = itemView.findViewById(R.id.rating);
category = itemView.findViewById(R.id.category);
posted = itemView.findViewById(R.id.posted);
simpleLanguage = itemView.findViewById(R.id.simple_language);
}
@Override
public View getSwipeableContainerView() {
return card;
}
}
private clreplaced HistoryAdapter extends RecyclerView.Adapter<HistoryHolder> implements SwipeableItemAdapter<HistoryHolder> {
private final LayoutInflater mInflater;
private final int mListThumbWidth;
private final int mListThumbHeight;
public HistoryAdapter() {
mInflater = getLayoutInflater2();
View calculator = mInflater.inflate(R.layout.item_gallery_list_thumb_height, null);
ViewUtils.measureView(calculator, 1024, ViewGroup.LayoutParams.WRAP_CONTENT);
mListThumbHeight = calculator.getMeasuredHeight();
mListThumbWidth = mListThumbHeight * 2 / 3;
}
@Override
public long gereplacedemId(int position) {
if (null == mLazyList) {
return super.gereplacedemId(position);
} else {
return mLazyList.get(position).gid;
}
}
@Override
public HistoryHolder onCreateViewHolder(ViewGroup parent, int viewType) {
HistoryHolder holder = new HistoryHolder(mInflater.inflate(R.layout.item_history, parent, false));
ViewGroup.LayoutParams lp = holder.thumb.getLayoutParams();
lp.width = mListThumbWidth;
lp.height = mListThumbHeight;
holder.thumb.setLayoutParams(lp);
return holder;
}
@Override
public void onBindViewHolder(HistoryHolder holder, int position) {
if (null == mLazyList) {
return;
}
GalleryInfo gi = mLazyList.get(position);
holder.thumb.load(EhCacheKeyFactory.getThumbKey(gi.gid), gi.thumb);
holder.replacedle.setText(EhUtils.getSuitablereplacedle(gi));
holder.uploader.setText(gi.uploader);
holder.rating.setRating(gi.rating);
TextView category = holder.category;
String newCategoryText = EhUtils.getCategory(gi.category);
if (!newCategoryText.equals(category.getText())) {
category.setText(newCategoryText);
category.setBackgroundColor(EhUtils.getCategoryColor(gi.category));
}
holder.posted.setText(gi.posted);
holder.simpleLanguage.setText(gi.simpleLanguage);
// Update transition name
long gid = gi.gid;
ViewCompat.setTransitionName(holder.thumb, TransitionNameFactory.getThumbTransitionName(gid));
holder.card.setOnClickListener(v -> onItemClick(holder.itemView, position));
holder.card.setOnLongClickListener(v -> onItemLongClick(position));
}
@Override
public int gereplacedemCount() {
return null != mLazyList ? mLazyList.size() : 0;
}
@Override
public int onGetSwipeReactionType(HistoryHolder holder, int position, int x, int y) {
return SwipeableItemConstants.REACTION_CAN_SWIPE_LEFT;
}
@Override
public void onSwipeItemStarted(HistoryHolder holder, int position) {
}
@Override
public void onSetSwipeBackground(HistoryHolder holder, int position, int type) {
}
@Override
public SwipeResultAction onSwipeItem(HistoryHolder holder, int position, int result) {
switch(result) {
case SwipeableItemConstants.RESULT_SWIPED_LEFT:
return new SwipeResultActionClear(position);
case SwipeableItemConstants.RESULT_SWIPED_RIGHT:
case SwipeableItemConstants.RESULT_CANCELED:
default:
return new SwipeResultActionDefault();
}
}
}
private clreplaced SwipeResultActionClear extends SwipeResultActionRemoveItem {
private final int mPosition;
protected SwipeResultActionClear(int position) {
mPosition = position;
}
@Override
protected void onPerformAction() {
super.onPerformAction();
if (null == mLazyList || null == mAdapter) {
return;
}
HistoryInfo info = mLazyList.get(mPosition);
EhDB.deleteHistoryInfo(info);
updateLazyList();
mAdapter.notifyDataSetChanged();
updateView(true);
}
}
}
16
Source : FavoritesScene.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
// TODO Get favorite, modify favorite, add favorite, what a mess!
public clreplaced FavoritesScene extends BaseScene implements FastScroller.OnDragHandlerListener, SearchBarMover.Helper, SearchBar.Helper, FabLayout.OnClickFabListener, FabLayout.OnExpandListener, EasyRecyclerView.CustomChoiceListener {
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";
// For modify action
private final List<GalleryInfo> mModifyGiList = new ArrayList<>();
// -1 for error
public int current;
// -1 for error
public int limit;
@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;
private AddDeleteDrawable mActionFabDrawable;
@Nullable
private EhDrawerLayout mDrawerLayout;
@Nullable
@DrawerLifeCircle
private FavDrawerAdapter mDrawerAdapter;
@Nullable
@WholeLifeCircle
private EhClient mClient;
@Nullable
@WholeLifeCircle
private String[] mFavCatArray;
@Nullable
@WholeLifeCircle
private int[] mFavCountArray;
@Nullable
@WholeLifeCircle
private FavListUrlBuilder mUrlBuilder;
private int mFavLocalCount = 0;
private int mFavCountSum = 0;
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 boolean mModifyAdd;
private final Runnable showNormalFabsRunnable = new Runnable() {
@Override
public void run() {
if (mFabLayout != null) {
mFabLayout.setSecondaryFabVisibilityAt(0, true);
mFabLayout.setSecondaryFabVisibilityAt(1, true);
mFabLayout.setSecondaryFabVisibilityAt(2, false);
mFabLayout.setSecondaryFabVisibilityAt(3, false);
mFabLayout.setSecondaryFabVisibilityAt(4, false);
}
}
};
@Override
public int getNavCheckedItem() {
return R.id.nav_favourite;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
mClient = EhApplication.getEhClient(context);
mFavCatArray = Settings.getFavCat();
mFavCountArray = Settings.getFavCount();
mFavLocalCount = Settings.getFavLocalCount();
mFavCountSum = Settings.getFavCloudCount();
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(@NonNull 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;
mFavCountArray = null;
mFavCountSum = 0;
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 = view.findViewById(R.id.content_layout);
MainActivity activity = getActivity2();
replacedertUtils.replacedertNotNull(activity);
mDrawerLayout = (EhDrawerLayout) ViewUtils.$$(activity, R.id.draw_view);
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();
replacedertUtils.replacedertNotNull(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);
contentLayout.setFitPaddingTop(paddingTopSB);
mAdapter = new FavoritesAdapter(inflater, resources, mRecyclerView, Settings.getListMode());
// mRecyclerView.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
// mRecyclerView.setDrawSelectorOnTop(true);
mRecyclerView.setClipToPadding(false);
mRecyclerView.setClipChildren(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());
mLeftDrawable = new DrawerArrowDrawable(context, AttrResources.getAttrColor(context, R.attr.drawableColorPrimary));
mSearchBar.setLeftDrawable(mLeftDrawable);
mSearchBar.setRightDrawable(DrawableManager.getVectorDrawable(context, R.drawable.v_magnify_x24));
mSearchBar.setHelper(this);
mSearchBar.setAllowEmptySearch(false);
updateSearchBar();
mSearchBarMover = new SearchBarMover(this, mSearchBar, mRecyclerView);
mActionFabDrawable = new AddDeleteDrawable(context, resources.getColor(R.color.primary_drawable_dark));
mFabLayout.getPrimaryFab().setImageDrawable(mActionFabDrawable);
mFabLayout.setExpanded(false, false);
mFabLayout.setAutoCancel(true);
mFabLayout.setHidePrimaryFab(false);
mFabLayout.setOnClickFabListener(this);
mFabLayout.setOnExpandListener(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);
Rect bounds = new Rect(point.x + LayoutUtils.dp2pix(requireContext(), 20), point.y / 3 + LayoutUtils.dp2pix(requireContext(), 20), point.x - LayoutUtils.dp2pix(requireContext(), 20), point.y / 3 - LayoutUtils.dp2pix(requireContext(), 20));
TapTargetView.showFor(requireActivity(), TapTarget.forBounds(bounds, getString(R.string.guide_collections_replacedle), getString(R.string.guide_collections_text)).transparentTarget(true), new TapTargetView.Listener() {
@Override
public void onTargetDismissed(TapTargetView view, boolean userInitiated) {
super.onTargetClick(view);
Settings.putGuideCollections(false);
openDrawer(Gravity.RIGHT);
}
});
}
// 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 replacedle
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.setreplacedle(getString(R.string.favorites_replacedle, favCatName));
}
} else {
if (!ObjectUtils.equal(favCatName, mOldFavCat) || !ObjectUtils.equal(keyword, mOldKeyword)) {
mSearchBar.setreplacedle(getString(R.string.favorites_replacedle_2, favCatName, keyword));
}
}
// Update hint
if (!ObjectUtils.equal(favCatName, mOldFavCat)) {
mSearchBar.setEditTextHint(getString(R.string.favorites_search_bar_hint, favCatName));
}
mOldFavCat = favCatName;
mOldKeyword = keyword;
// Save recent fav cat
Settings.putRecentFavCat(mUrlBuilder.getFavCat());
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mHelper) {
mHelper.destroy();
if (1 == mHelper.getShownViewIndex()) {
mHasFirstRefresh = false;
}
}
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;
}
@Override
public View onCreateDrawerView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.drawer_list_rv, container, false);
final Context context = getContext2();
Toolbar toolbar = (Toolbar) ViewUtils.$$(view, R.id.toolbar);
replacedertUtils.replacedertNotNull(context);
toolbar.setreplacedle(R.string.collections);
toolbar.inflateMenu(R.menu.drawer_favorites);
toolbar.setOnMenuItemClickListener(item -> {
int id = item.gereplacedemId();
if (id == 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 MaterialAlertDialogBuilder(context).setreplacedle(R.string.default_favorites_collection).sereplacedems(items, (dialog, which) -> Settings.putDefaultFavSlot(which - 2)).show();
return true;
}
return false;
});
EasyRecyclerView recyclerView = view.findViewById(R.id.recycler_view_drawer);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setShowLastDivider(true);
recyclerView.addItemDecoration(decoration);
mDrawerAdapter = new FavDrawerAdapter(inflater);
recyclerView.setAdapter(mDrawerAdapter);
return view;
}
@Override
public void onDestroyDrawerView() {
super.onDestroyDrawerView();
mDrawerAdapter = null;
}
@Override
public void onBackPressed() {
if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) {
mRecyclerView.outOfCustomChoiceMode();
} else if (mFabLayout != null && mFabLayout.isExpanded()) {
mFabLayout.toggle();
} else if (mSearchMode) {
exitSearchMode(true);
} else {
finish();
}
}
@Override
@Implemented(FastScroller.OnDragHandlerListener.clreplaced)
public void onStartDragHandler() {
// Lock right drawer
setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.RIGHT);
}
@Override
@Implemented(FastScroller.OnDragHandlerListener.clreplaced)
public void onEndDragHandler() {
// Restore right drawer
if (null != mRecyclerView && !mRecyclerView.isInCustomChoice()) {
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.RIGHT);
}
if (mSearchBarMover != null) {
mSearchBarMover.returnSearchBarPosition();
}
}
public boolean onItemClick(View view, int position) {
if (mDrawerLayout != null && mDrawerLayout.isDrawerOpen(Gravity.RIGHT)) {
// Skip if in search mode
if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) {
return true;
}
if (mUrlBuilder == null || mHelper == null) {
return true;
}
// 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 true;
}
// Ensure outOfCustomChoiceMode to avoid error
if (mRecyclerView != null) {
mRecyclerView.isInCustomChoice();
}
exitSearchMode(true);
mUrlBuilder.setKeyword(null);
mUrlBuilder.setFavCat(newFavCat);
updateSearchBar();
mHelper.refresh();
closeDrawer(Gravity.RIGHT);
} else {
if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) {
mRecyclerView.toggleItemChecked(position);
} else if (mHelper != null) {
GalleryInfo gi = mHelper.getDataAtEx(position);
if (gi == null) {
return true;
}
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.clreplaced).setArgs(args);
View thumb;
if (null != (thumb = view.findViewById(R.id.thumb))) {
announcer.setTranHelper(new EnterGalleryDetailTransaction(thumb));
}
startScene(announcer);
}
}
return true;
}
public boolean onItemLongClick(View view, int position) {
// Can not into
if (mRecyclerView != null && !mSearchMode) {
if (!mRecyclerView.isInCustomChoice()) {
mRecyclerView.intoCustomChoiceMode();
}
mRecyclerView.toggleItemChecked(position);
}
return true;
}
@Override
@Implemented(SearchBarMover.Helper.clreplaced)
public boolean isValidView(RecyclerView recyclerView) {
return recyclerView == mRecyclerView;
}
@Override
@Implemented(SearchBarMover.Helper.clreplaced)
public RecyclerView getValidRecyclerView() {
return mRecyclerView;
}
@Override
@Implemented(SearchBarMover.Helper.clreplaced)
public boolean forceShowSearchBar() {
return false;
}
@Override
@Implemented(SearchBar.Helper.clreplaced)
public void onClickreplacedle() {
// Skip if in search mode
if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) {
return;
}
if (!mSearchMode) {
enterSearchMode(true);
}
}
@Override
@Implemented(SearchBar.Helper.clreplaced)
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.clreplaced)
public void onClickRightIcon() {
// Skip if in search mode
if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) {
return;
}
if (!mSearchMode) {
enterSearchMode(true);
} else if (mSearchBar != null) {
if (mSearchBar.getEditText().length() == 0) {
exitSearchMode(true);
} else {
mSearchBar.applySearch();
}
}
}
@Override
@Implemented(SearchBar.Helper.clreplaced)
public void onSearchEditTextClick() {
}
@Override
@Implemented(SearchBar.Helper.clreplaced)
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.clreplaced)
public void onSearchEditTextBackPressed() {
onBackPressed();
}
@Override
public void onExpand(boolean expanded) {
if (expanded) {
mActionFabDrawable.setDelete(ANIMATE_TIME);
} else {
mActionFabDrawable.setAdd(ANIMATE_TIME);
}
}
@Override
@Implemented(FabLayout.OnClickFabListener.clreplaced)
public void onClickPrimaryFab(FabLayout view, FloatingActionButton fab) {
if (mRecyclerView != null && mFabLayout != null) {
if (mRecyclerView.isInCustomChoice()) {
mRecyclerView.outOfCustomChoiceMode();
} else {
mFabLayout.toggle();
}
}
}
private void showGoToDialog() {
Context context = getContext2();
if (null == context || null == mHelper) {
return;
}
final int page = mHelper.getPageForTop();
final int pages = mHelper.getPages();
String hint = getString(R.string.go_to_hint, page + 1, pages);
final EditTextDialogBuilder builder = new EditTextDialogBuilder(context, null, hint);
builder.getEditText().setInputType(InputType.TYPE_CLreplaced_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
final AlertDialog dialog = builder.setreplacedle(R.string.go_to).setPositiveButton(android.R.string.ok, null).show();
dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(v -> {
if (null == mHelper) {
dialog.dismiss();
return;
}
String text = builder.getText().trim();
int goTo;
try {
goTo = Integer.parseInt(text) - 1;
} catch (NumberFormatException e) {
builder.setError(getString(R.string.error_invalid_number));
return;
}
if (goTo < 0 || goTo >= pages) {
builder.setError(getString(R.string.error_out_of_range));
return;
}
builder.setError(null);
mHelper.goTo(goTo);
AppHelper.hideSoftInput(dialog);
dialog.dismiss();
});
}
@Override
@Implemented(FabLayout.OnClickFabListener.clreplaced)
public void onClickSecondaryFab(FabLayout view, FloatingActionButton fab, int position) {
Context context = getContext2();
if (null == context || null == mRecyclerView || null == mHelper) {
return;
}
if (!mRecyclerView.isInCustomChoice()) {
switch(position) {
case // Open right
0:
openDrawer(Gravity.RIGHT);
break;
case // Go to
1:
if (mHelper.canGoTo()) {
showGoToDialog();
}
break;
case // Refresh
2:
mHelper.refresh();
break;
}
view.setExpanded(false);
return;
}
mModifyGiList.clear();
SparseBooleanArray stateArray = mRecyclerView.getCheckedItemPositions();
for (int i = 0, n = stateArray.size(); i < n; i++) {
if (stateArray.valueAt(i)) {
GalleryInfo gi = mHelper.getDataAtEx(stateArray.keyAt(i));
if (gi != null) {
mModifyGiList.add(gi);
}
}
}
switch(position) {
case 3:
{
// Download
Activity activity = getActivity2();
if (activity != null) {
CommonOperations.startDownload(getActivity2(), mModifyGiList, false);
}
mModifyGiList.clear();
if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) {
mRecyclerView.outOfCustomChoiceMode();
}
break;
}
case 4:
{
// Delete
DeleteDialogHelper helper = new DeleteDialogHelper();
new MaterialAlertDialogBuilder(context).setreplacedle(R.string.delete_favorites_dialog_replacedle).setMessage(getString(R.string.delete_favorites_dialog_message, mModifyGiList.size())).setPositiveButton(android.R.string.ok, helper).setOnCancelListener(helper).show();
break;
}
case 5:
{
// 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 MaterialAlertDialogBuilder(context).setreplacedle(R.string.move_favorites_dialog_replacedle).sereplacedems(array, helper).setOnCancelListener(helper).show();
break;
}
}
}
private void showNormalFabs() {
// Delay showing normal fabs to avoid mutation
SimpleHandler.getInstance().removeCallbacks(showNormalFabsRunnable);
SimpleHandler.getInstance().postDelayed(showNormalFabsRunnable, 300);
}
private void showSelectionFabs() {
SimpleHandler.getInstance().removeCallbacks(showNormalFabsRunnable);
if (mFabLayout != null) {
mFabLayout.setSecondaryFabVisibilityAt(0, false);
mFabLayout.setSecondaryFabVisibilityAt(1, false);
mFabLayout.setSecondaryFabVisibilityAt(2, true);
mFabLayout.setSecondaryFabVisibilityAt(3, true);
mFabLayout.setSecondaryFabVisibilityAt(4, true);
}
}
@Override
@Implemented(EasyRecyclerView.CustomChoiceListener.clreplaced)
public void onIntoCustomChoice(EasyRecyclerView view) {
if (mFabLayout != null) {
showSelectionFabs();
mFabLayout.setAutoCancel(false);
// Delay expanding action to make layout work fine
SimpleHandler.getInstance().post(() -> 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.clreplaced)
public void onOutOfCustomChoice(EasyRecyclerView view) {
if (mFabLayout != null) {
showNormalFabs();
mFabLayout.setAutoCancel(true);
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.clreplaced)
public void onItemCheckedStateChanged(EasyRecyclerView view, int position, long id, boolean checked) {
if (view.getCheckedItemCount() == 0) {
view.outOfCustomChoiceMode();
}
}
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) {
System.arraycopy(result.catArray, 0, mFavCatArray, 0, 10);
}
mFavCountArray = result.countArray;
if (mFavCountArray != null) {
mFavCountSum = 0;
for (int i = 0; i < 10; i++) {
mFavCountSum = mFavCountSum + mFavCountArray[i];
}
Settings.putFavCloudCount(mFavCountSum);
}
updateSearchBar();
mHelper.onGetPageData(taskId, result.pages, result.nextPage, result.galleryInfoList);
if (mDrawerAdapter != null) {
mDrawerAdapter.notifyDataSetChanged();
}
}
}
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.onGetPageData(taskId, 0, 0, Collections.EMPTY_LIST);
} else {
mHelper.onGetPageData(taskId, 1, 0, list);
}
if (TextUtils.isEmpty(keyword)) {
mFavLocalCount = list.size();
Settings.putFavLocalCount(mFavLocalCount);
if (mDrawerAdapter != null) {
mDrawerAdapter.notifyDataSetChanged();
}
}
}
}
private static clreplaced AddFavoritesListener extends EhCallback<FavoritesScene, Void> {
private final int mTaskId;
private final String mKeyword;
private final List<GalleryInfo> mBackup;
private AddFavoritesListener(Context context, int stageId, String sceneTag, int taskId, String keyword, List<GalleryInfo> backup) {
super(context, stageId, sceneTag);
mTaskId = taskId;
mKeyword = keyword;
mBackup = backup;
}
@Override
public void onSuccess(Void result) {
FavoritesScene scene = getScene();
if (scene != null) {
scene.onGetFavoritesLocal(mKeyword, mTaskId);
}
}
@Override
public void onFailure(Exception e) {
// TODO It's a failure, add all of backup back to db.
// But how to known which one is failed?
EhDB.putLocalFavorites(mBackup);
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 clreplaced 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;
private 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);
Settings.putFavCount(result.countArray);
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;
}
}
private clreplaced FavDrawerHolder extends RecyclerView.ViewHolder {
private final TextView key;
private final TextView value;
private FavDrawerHolder(View itemView) {
super(itemView);
key = (TextView) ViewUtils.$$(itemView, R.id.key);
value = (TextView) ViewUtils.$$(itemView, R.id.value);
}
}
private clreplaced FavDrawerAdapter extends RecyclerView.Adapter<FavDrawerHolder> {
private final LayoutInflater mInflater;
private FavDrawerAdapter(LayoutInflater inflater) {
mInflater = inflater;
}
@Override
public int gereplacedemViewType(int position) {
return position;
}
@NonNull
@Override
public FavDrawerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new FavDrawerHolder(mInflater.inflate(R.layout.item_drawer_favorites, parent, false));
}
@Override
@SuppressLint("SetTextI18n")
public void onBindViewHolder(@NonNull FavDrawerHolder holder, int position) {
if (0 == position) {
holder.key.setText(R.string.local_favorites);
holder.value.setText(Integer.toString(mFavLocalCount));
holder.itemView.setEnabled(true);
} else if (1 == position) {
holder.key.setText(R.string.cloud_favorites);
holder.value.setText(Integer.toString(mFavCountSum));
holder.itemView.setEnabled(true);
} else {
if (null == mFavCatArray || null == mFavCountArray || mFavCatArray.length < (position - 1) || mFavCountArray.length < (position - 1)) {
return;
}
holder.key.setText(mFavCatArray[position - 2]);
holder.value.setText(Integer.toString(mFavCountArray[position - 2]));
holder.itemView.setEnabled(true);
}
holder.itemView.setOnClickListener(v -> onItemClick(holder.itemView, position));
}
@Override
public int gereplacedemCount() {
if (null == mFavCatArray) {
return 2;
}
return 12;
}
}
private clreplaced 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 clreplaced 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 clreplaced FavoritesAdapter extends GalleryAdapter {
public FavoritesAdapter(@NonNull LayoutInflater inflater, @NonNull Resources resources, @NonNull RecyclerView recyclerView, int type) {
super(inflater, resources, recyclerView, type, false);
}
@Override
public int gereplacedemCount() {
return null != mHelper ? mHelper.size() : 0;
}
@Override
void onItemClick(View view, int position) {
FavoritesScene.this.onItemClick(view, position);
}
@Override
boolean onItemLongClick(View view, int position) {
return FavoritesScene.this.onItemLongClick(view, position);
}
@Nullable
@Override
public GalleryInfo getDataAt(int position) {
return null != mHelper ? mHelper.getDataAtEx(position) : null;
}
}
private clreplaced FavoritesHelper extends GalleryInfoContentHelper {
@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;
}
List<GalleryInfo> modifyGiListBackup = new ArrayList<>(mModifyGiList);
mModifyGiList.clear();
EhRequest request = new EhRequest();
request.setMethod(EhClient.METHOD_ADD_FAVORITES_RANGE);
request.setCallback(new AddFavoritesListener(getContext(), activity.getStageId(), getTag(), taskId, mUrlBuilder.getKeyword(), modifyGiListBackup));
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.getShowJpnreplacedle());
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.getShowJpnreplacedle());
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 boolean isDuplicate(GalleryInfo d1, GalleryInfo d2) {
return d1.gid == d2.gid;
}
@Override
protected void onScrollToPosition(int postion) {
if (0 == postion) {
if (null != mSearchBarMover) {
mSearchBarMover.showSearchBar();
}
}
}
}
}
16
Source : FavoritesScene.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
@Override
@Implemented(EasyRecyclerView.CustomChoiceListener.clreplaced)
public void onItemCheckedStateChanged(EasyRecyclerView view, int position, long id, boolean checked) {
if (view.getCheckedItemCount() == 0) {
view.outOfCustomChoiceMode();
}
}
16
Source : FavoritesScene.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
@Override
@Implemented(EasyRecyclerView.CustomChoiceListener.clreplaced)
public void onOutOfCustomChoice(EasyRecyclerView view) {
if (mFabLayout != null) {
showNormalFabs();
mFabLayout.setAutoCancel(true);
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);
}
16
Source : ContentLayout.java
with Apache License 2.0
from duzhaokun123
with Apache License 2.0
from duzhaokun123
public clreplaced ContentLayout extends FrameLayout {
private CircularProgressIndicator mProgressView;
private TextView mTipView;
private ViewGroup mContentView;
private SwipeRefreshLayout mRefreshLayout;
private LinearProgressIndicator mBottomProgress;
private EasyRecyclerView mRecyclerView;
private FastScroller mFastScroller;
private ContentHelper<?> mContentHelper;
private int mRecyclerViewOriginTop;
private int mRecyclerViewOriginBottom;
public ContentLayout(Context context) {
super(context);
init(context);
}
public ContentLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ContentLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
LayoutInflater.from(context).inflate(R.layout.widget_content_layout, this);
setClipChildren(false);
setClipToPadding(false);
mProgressView = findViewById(R.id.progress);
mTipView = findViewById(R.id.tip);
mContentView = findViewById(R.id.content_view);
mRefreshLayout = mContentView.findViewById(R.id.refresh_layout);
mBottomProgress = mContentView.findViewById(R.id.bottom_progress);
mFastScroller = mContentView.findViewById(R.id.fast_scroller);
mRecyclerView = mRefreshLayout.findViewById(R.id.recycler_view);
mFastScroller.attachToRecyclerView(mRecyclerView);
HandlerDrawable drawable = new HandlerDrawable();
drawable.setColor(AttrResources.getAttrColor(context, R.attr.widgetColorThemeAccent));
mFastScroller.setHandlerDrawable(drawable);
mRefreshLayout.setColorSchemeResources(R.color.loading_indicator_red, R.color.loading_indicator_purple, R.color.loading_indicator_blue, R.color.loading_indicator_cyan, R.color.loading_indicator_green, R.color.loading_indicator_yellow);
Resources resources = getResources();
mBottomProgress.setIndicatorColor(resources.getColor(R.color.loading_indicator_red), resources.getColor(R.color.loading_indicator_blue), resources.getColor(R.color.loading_indicator_green), resources.getColor(R.color.loading_indicator_orange));
mBottomProgress.setIndeterminateAnimationType(LinearProgressIndicator.INDETERMINATE_ANIMATION_TYPE_CONTIGUOUS);
mRecyclerViewOriginTop = mRecyclerView.getPaddingTop();
mRecyclerViewOriginBottom = mRecyclerView.getPaddingBottom();
}
@NonNull
public EasyRecyclerView getRecyclerView() {
return mRecyclerView;
}
public FastScroller getFastScroller() {
return mFastScroller;
}
public SwipeRefreshLayout getRefreshLayout() {
return mRefreshLayout;
}
public void setHelper(ContentHelper<?> helper) {
mContentHelper = helper;
helper.init(this);
}
public void showFastScroll() {
if (!mFastScroller.isAttached()) {
mFastScroller.attachToRecyclerView(mRecyclerView);
}
}
public void hideFastScroll() {
mFastScroller.detachedFromRecyclerView();
}
public void setFitPaddingTop(int fitPaddingTop) {
// RecyclerView
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerViewOriginTop + fitPaddingTop, mRecyclerView.getPaddingRight(), mRecyclerView.getPaddingBottom());
// RefreshLayout
// TODO
mRefreshLayout.setProgressViewOffset(true, 0, fitPaddingTop + LayoutUtils.dp2pix(getContext(), 32));
}
public void setTopInsets(int topInsets) {
setPadding(0, topInsets, 0, 0);
}
public void setFitPaddingBottom(int fitPaddingBottom) {
// RecyclerView
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), mRecyclerViewOriginBottom + fitPaddingBottom);
mTipView.setPadding(mTipView.getPaddingLeft(), mTipView.getPaddingTop(), mTipView.getPaddingRight(), fitPaddingBottom);
mProgressView.setPadding(mProgressView.getPaddingLeft(), mProgressView.getPaddingTop(), mProgressView.getPaddingRight(), fitPaddingBottom);
mFastScroller.setPadding(mFastScroller.getPaddingLeft(), mFastScroller.getPaddingTop(), mFastScroller.getPaddingRight(), fitPaddingBottom);
if (fitPaddingBottom > LayoutUtils.dp2pix(getContext(), 16)) {
mBottomProgress.setPadding(0, 0, 0, fitPaddingBottom);
} else {
mBottomProgress.setPadding(0, 0, 0, 0);
}
}
@Override
protected Parcelable onSaveInstanceState() {
return mContentHelper.saveInstanceState(super.onSaveInstanceState());
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(mContentHelper.restoreInstanceState(state));
}
public abstract static clreplaced ContentHelper<E extends Parcelable> implements ViewTransition.OnShowViewListener {
public static final int TYPE_REFRESH = 0;
public static final int TYPE_PRE_PAGE = 1;
public static final int TYPE_PRE_PAGE_KEEP_POS = 2;
public static final int TYPE_NEXT_PAGE = 3;
public static final int TYPE_NEXT_PAGE_KEEP_POS = 4;
public static final int TYPE_SOMEWHERE = 5;
public static final int TYPE_REFRESH_PAGE = 6;
public static final int REFRESH_TYPE_HEADER = 0;
public static final int REFRESH_TYPE_FOOTER = 1;
public static final int REFRESH_TYPE_PROGRESS_VIEW = 2;
private static final String TAG = ContentHelper.clreplaced.getSimpleName();
private static final int CHECK_DUPLICATE_RANGE = 50;
private static final String KEY_SUPER = "super";
private static final String KEY_SHOWN_VIEW = "shown_view";
private static final String KEY_TIP = "tip";
private static final String KEY_DATA = "data";
private static final String KEY_NEXT_ID = "next_id";
private static final String KEY_PAGE_DIVIDER = "page_divider";
private static final String KEY_START_PAGE = "start_page";
private static final String KEY_END_PAGE = "end_page";
private static final String KEY_PAGES = "pages";
/**
* Generate task id
*/
private final IntIdGenerator mIdGenerator = new IntIdGenerator();
private final LayoutManagerUtils.OnScrollToPositionListener mOnScrollToPositionListener = ContentHelper.this::onScrollToPosition;
private CircularProgressIndicator mProgressView;
private TextView mTipView;
private ViewGroup mContentView;
private SwipeRefreshLayout mRefreshLayout;
private LinearProgressIndicator mBottomProgress;
private EasyRecyclerView mRecyclerView;
private ViewTransition mViewTransition;
/**
* Store data
*/
private ArrayList<E> mData = new ArrayList<>();
/**
* Store the page divider index
* <p>
* For example, the data contain page 3, page 4, page 5,
* page 3 size is 7, page 4 size is 8, page 5 size is 9,
* so <code>mPageDivider</code> contain 7, 15, 24.
*/
private IntList mPageDivider = new IntList();
/**
* The first page in <code>mData</code>
*/
private int mStartPage;
/**
* The last page + 1 in <code>mData</code>
*/
private int mEndPage;
/**
* The available page count.
*/
private int mPages;
private int mNextPage;
private int mCurrentTaskId;
private int mCurrentTaskType;
private int mCurrentTaskPage;
private int mNextPageScrollSize;
private String mEmptyString = "No hint";
private final SwipeRefreshLayout.OnRefreshListener mOnRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
if (mStartPage > 0) {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_PRE_PAGE_KEEP_POS;
mCurrentTaskPage = mStartPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
doRefresh();
}
}
};
private final RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (!mRefreshLayout.isRefreshing() && !recyclerView.canScrollVertically(1) && mEndPage < mPages) {
// Get next page
mBottomProgress.show();
if (mEndPage < mPages) {
// Get next page
// Fill pages before NextPage with empty list
while (mNextPage > mEndPage && mEndPage < mPages) {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
onGetPageData(mCurrentTaskId, mPages, mNextPage, Collections.emptyList());
}
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else if (mEndPage == mPages) {
// Refresh last page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_REFRESH_PAGE;
mCurrentTaskPage = mEndPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
Log.e(TAG, "Try to footer refresh, but mEndPage = " + mEndPage + ", mPages = " + mPages);
mBottomProgress.hide();
}
}
}
};
private int mSavedDataId = IntIdGenerator.INVALID_ID;
private void init(ContentLayout contentLayout) {
mNextPageScrollSize = LayoutUtils.dp2pix(contentLayout.getContext(), 48);
mProgressView = contentLayout.mProgressView;
mTipView = contentLayout.mTipView;
mContentView = contentLayout.mContentView;
mRefreshLayout = contentLayout.mRefreshLayout;
mBottomProgress = contentLayout.mBottomProgress;
mRecyclerView = contentLayout.mRecyclerView;
Drawable drawable = ContextCompat.getDrawable(getContext(), R.drawable.big_sad_pandroid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
mTipView.setCompoundDrawables(null, drawable, null, null);
mViewTransition = new ViewTransition(mContentView, mProgressView, mTipView);
mViewTransition.setOnShowViewListener(this);
mRecyclerView.addOnScrollListener(mOnScrollListener);
mRefreshLayout.setOnRefreshListener(mOnRefreshListener);
mTipView.setOnClickListener(v -> refresh());
}
/**
* Call {@link #onGetPageData(int, int, int, List)} when get data
*
* @param taskId task id
* @param page the page to get
*/
protected abstract void getPageData(int taskId, int type, int page);
protected abstract Context getContext();
protected abstract void notifyDataSetChanged();
protected abstract void notifyItemRangeRemoved(int positionStart, int itemCount);
protected abstract void notifyItemRangeInserted(int positionStart, int itemCount);
protected void onScrollToPosition(int postion) {
}
@Override
public void onShowView(View hiddenView, View shownView) {
}
public int getShownViewIndex() {
return mViewTransition.getShownViewIndex();
}
public void setRefreshLayoutEnable(boolean enable) {
mRefreshLayout.setEnabled(enable);
}
public void setEnable(boolean enable) {
mRefreshLayout.setEnabled(enable);
}
public void setEmptyString(String str) {
mEmptyString = str;
}
public List<E> getData() {
return mData;
}
/**
* @throws IndexOutOfBoundsException if {@code location < 0 || location >= size()}
*/
public E getDataAt(int location) {
return mData.get(location);
}
@Nullable
public E getDataAtEx(int location) {
if (location >= 0 && location < mData.size()) {
return mData.get(location);
} else {
return null;
}
}
public int size() {
return mData.size();
}
public boolean isCurrentTask(int taskId) {
return mCurrentTaskId == taskId;
}
public int getPages() {
return mPages;
}
public void addAt(int index, E data) {
mData.add(index, data);
onAddData(data);
for (int i = 0, n = mPageDivider.size(); i < n; i++) {
int divider = mPageDivider.get(i);
if (index < divider) {
mPageDivider.set(i, divider + 1);
}
}
notifyItemRangeInserted(index, 1);
}
public void removeAt(int index) {
E data = mData.remove(index);
onRemoveData(data);
for (int i = 0, n = mPageDivider.size(); i < n; i++) {
int divider = mPageDivider.get(i);
if (index < divider) {
mPageDivider.set(i, divider - 1);
}
}
notifyItemRangeRemoved(index, 1);
}
protected abstract boolean isDuplicate(E d1, E d2);
private void removeDuplicateData(List<E> data, int start, int end) {
start = Math.max(0, start);
end = Math.min(mData.size(), end);
for (Iterator<E> iterator = data.iterator(); iterator.hasNext(); ) {
E d = iterator.next();
for (int i = start; i < end; i++) {
if (isDuplicate(d, mData.get(i))) {
iterator.remove();
break;
}
}
}
}
protected void onAddData(E data) {
}
protected void onAddData(List<E> data) {
}
protected void onRemoveData(E data) {
}
protected void onRemoveData(List<E> data) {
}
protected void onClearData() {
}
public void onGetPageData(int taskId, int pages, int nextPage, List<E> data) {
if (mCurrentTaskId == taskId) {
int dataSize;
switch(mCurrentTaskType) {
case TYPE_REFRESH:
mStartPage = 0;
mEndPage = 1;
mPages = pages;
mNextPage = nextPage;
mPageDivider.clear();
mPageDivider.add(data.size());
if (data.isEmpty()) {
mData.clear();
onClearData();
notifyDataSetChanged();
if (true || mEndPage >= mPages) {
// Not found
// Ui change, show empty string
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showProgressBar();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.clear();
onClearData();
mData.addAll(data);
onAddData(data);
notifyDataSetChanged();
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
// RecyclerView scroll
if (mRecyclerView.isAttachedToWindow()) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
break;
case TYPE_PRE_PAGE:
case TYPE_PRE_PAGE_KEEP_POS:
removeDuplicateData(data, 0, CHECK_DUPLICATE_RANGE);
dataSize = data.size();
for (int i = 0, n = mPageDivider.size(); i < n; i++) {
mPageDivider.set(i, mPageDivider.get(i) + dataSize);
}
mPageDivider.add(0, dataSize);
mStartPage--;
mPages = Math.max(mEndPage, pages);
// replacedert mStartPage >= 0
if (data.isEmpty()) {
if (true || mStartPage <= 0) {
// OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mCurrentTaskType == TYPE_PRE_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll, to top
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
} else {
// Keep UI
// Get previous
mCurrentTaskId = mIdGenerator.nextId();
// Keep mCurrentTaskType
mCurrentTaskPage = mStartPage - 1;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.addAll(0, data);
onAddData(data);
notifyItemRangeInserted(0, data.size());
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
if (mCurrentTaskType == TYPE_PRE_PAGE_KEEP_POS) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionProperly(mRecyclerView.getLayoutManager(), getContext(), dataSize - 1, mOnScrollToPositionListener);
} else {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
}
break;
case TYPE_NEXT_PAGE:
case TYPE_NEXT_PAGE_KEEP_POS:
removeDuplicateData(data, mData.size() - CHECK_DUPLICATE_RANGE, mData.size());
dataSize = data.size();
int oldDataSize = mData.size();
mPageDivider.add(oldDataSize + dataSize);
mEndPage++;
mNextPage = nextPage;
mPages = Math.max(mEndPage, pages);
if (data.isEmpty()) {
if (true || mEndPage >= mPages) {
// OK, that's all
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mCurrentTaskType == TYPE_NEXT_PAGE && mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), oldDataSize, 0);
onScrollToPosition(oldDataSize);
}
}
} else {
// Keep UI
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
// Keep mCurrentTaskType
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.addAll(data);
onAddData(data);
notifyItemRangeInserted(oldDataSize, dataSize);
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mRecyclerView.isAttachedToWindow()) {
if (mCurrentTaskType == TYPE_NEXT_PAGE_KEEP_POS) {
mRecyclerView.stopScroll();
mRecyclerView.smoothScrollBy(0, mNextPageScrollSize);
} else {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), oldDataSize, 0);
onScrollToPosition(oldDataSize);
}
}
}
break;
case TYPE_SOMEWHERE:
mStartPage = mCurrentTaskPage;
mEndPage = mCurrentTaskPage + 1;
mNextPage = nextPage;
mPages = pages;
mPageDivider.clear();
mPageDivider.add(data.size());
if (data.isEmpty()) {
mData.clear();
onClearData();
notifyDataSetChanged();
if (true || mEndPage >= mPages) {
// Not found
// Ui change, show empty string
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show progress bar
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showProgressBar();
// Get next page
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE_KEEP_POS;
mCurrentTaskPage = mEndPage;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
} else {
mData.clear();
onClearData();
mData.addAll(data);
onAddData(data);
notifyDataSetChanged();
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
if (mRecyclerView.isAttachedToWindow()) {
// RecyclerView scroll
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), 0, 0);
onScrollToPosition(0);
}
}
break;
case TYPE_REFRESH_PAGE:
if (mCurrentTaskPage < mStartPage || mCurrentTaskPage >= mEndPage) {
Log.e(TAG, "TYPE_REFRESH_PAGE, but mCurrentTaskPage = " + mCurrentTaskPage + ", mStartPage = " + mStartPage + ", mEndPage = " + mEndPage);
break;
}
if (mCurrentTaskPage == mEndPage - 1) {
mNextPage = nextPage;
}
mPages = Math.max(mEndPage, pages);
int oldIndexStart = mCurrentTaskPage == mStartPage ? 0 : mPageDivider.get(mCurrentTaskPage - mStartPage - 1);
int oldIndexEnd = mPageDivider.get(mCurrentTaskPage - mStartPage);
List<E> toRemove = mData.subList(oldIndexStart, oldIndexEnd);
onRemoveData(toRemove);
toRemove.clear();
removeDuplicateData(data, oldIndexStart - CHECK_DUPLICATE_RANGE, oldIndexStart + CHECK_DUPLICATE_RANGE);
int newIndexStart = oldIndexStart;
int newIndexEnd = newIndexStart + data.size();
mData.addAll(oldIndexStart, data);
onAddData(data);
notifyDataSetChanged();
for (int i = mCurrentTaskPage - mStartPage, n = mPageDivider.size(); i < n; i++) {
mPageDivider.set(i, mPageDivider.get(i) - oldIndexEnd + newIndexEnd);
}
if (mData.isEmpty()) {
// Ui change, show empty string
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showEmptyString();
} else {
// Ui change, show content
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
showContent();
// RecyclerView scroll
if (newIndexEnd > oldIndexEnd && newIndexEnd > 0 && mRecyclerView.isAttachedToWindow()) {
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), newIndexEnd - 1, 0);
onScrollToPosition(newIndexEnd - 1);
}
}
break;
}
}
}
public void onGetException(int taskId, Exception e) {
if (mCurrentTaskId == taskId) {
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
String readableError;
if (e != null) {
e.printStackTrace();
readableError = ExceptionUtils.getReadableString(e);
} else {
readableError = getContext().getString(R.string.error_unknown);
}
if (mViewTransition.getShownViewIndex() == 0) {
Toast.makeText(getContext(), readableError, Toast.LENGTH_SHORT).show();
} else {
showText(readableError);
}
}
}
public void showContent() {
mViewTransition.showView(0);
}
private boolean isContentShowing() {
return mViewTransition.getShownViewIndex() == 0;
}
public void showProgressBar() {
showProgressBar(true);
}
public void showProgressBar(boolean animation) {
mViewTransition.showView(1, animation);
}
public void showText(CharSequence text) {
mTipView.setText(text);
mViewTransition.showView(2);
}
public void showEmptyString() {
showText(mEmptyString);
}
/**
* Be carefull
*/
public void doGetData(int type, int page, int refreshType) {
switch(refreshType) {
default:
case REFRESH_TYPE_HEADER:
showContent();
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
break;
case REFRESH_TYPE_FOOTER:
showContent();
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
break;
case REFRESH_TYPE_PROGRESS_VIEW:
showProgressBar();
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
break;
}
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = type;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
private void doRefresh() {
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_REFRESH;
mCurrentTaskPage = 0;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
/**
* Lisk {@link #refresh()}, but no animation when show progress bar
*/
public void firstRefresh() {
showProgressBar(false);
doRefresh();
}
/**
* Show progress bar first, than do refresh
*/
public void refresh() {
showProgressBar();
doRefresh();
}
private void cancelCurrentTask() {
mCurrentTaskId = mIdGenerator.nextId();
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
}
private int getPageStart(int page) {
if (mStartPage == page) {
return 0;
} else {
return mPageDivider.get(page - mStartPage - 1);
}
}
private int getPageEnd(int page) {
return mPageDivider.get(page - mStartPage);
}
private int getPageForPosition(int position) {
if (position < 0) {
return -1;
}
IntList pageDivider = mPageDivider;
for (int i = 0, n = pageDivider.size(); i < n; i++) {
if (position < pageDivider.get(i)) {
return i + mStartPage;
}
}
return -1;
}
public int getPageForTop() {
return getPageForPosition(LayoutManagerUtils.getFirstVisibleItemPosition(mRecyclerView.getLayoutManager()));
}
public int getPageForBottom() {
return getPageForPosition(LayoutManagerUtils.getLastVisibleItemPosition(mRecyclerView.getLayoutManager()));
}
public boolean canGoTo() {
return isContentShowing();
}
/**
* Check range first!
*
* @param page the target page
* @throws IndexOutOfBoundsException
*/
public void goTo(int page) throws IndexOutOfBoundsException {
if (page < 0 || page >= mPages) {
throw new IndexOutOfBoundsException("Page count is " + mPages + ", page is " + page);
} else if (page >= mStartPage && page < mEndPage) {
cancelCurrentTask();
int position = getPageStart(page);
mRecyclerView.stopScroll();
LayoutManagerUtils.scrollToPositionWithOffset(mRecyclerView.getLayoutManager(), position, 0);
onScrollToPosition(position);
} else if (page == mStartPage - 1) {
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_PRE_PAGE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else if (page == mEndPage) {
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_NEXT_PAGE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
} else {
mRefreshLayout.setRefreshing(false);
mBottomProgress.hide();
mCurrentTaskId = mIdGenerator.nextId();
mCurrentTaskType = TYPE_SOMEWHERE;
mCurrentTaskPage = page;
getPageData(mCurrentTaskId, mCurrentTaskType, mCurrentTaskPage);
}
}
protected Parcelable saveInstanceState(Parcelable superState) {
Bundle bundle = new Bundle();
bundle.putParcelable(KEY_SUPER, superState);
int shownView = mViewTransition.getShownViewIndex();
bundle.putInt(KEY_SHOWN_VIEW, shownView);
bundle.putString(KEY_TIP, mTipView.getText().toString());
// TODO It's a bad design
EhApplication app = (EhApplication) getContext().getApplicationContext();
if (mSavedDataId != IntIdGenerator.INVALID_ID) {
app.removeGlobalStuff(mSavedDataId);
mSavedDataId = IntIdGenerator.INVALID_ID;
}
mSavedDataId = app.putGlobalStuff(mData);
bundle.putInt(KEY_DATA, mSavedDataId);
bundle.putInt(KEY_NEXT_ID, mIdGenerator.nextId());
bundle.putParcelable(KEY_PAGE_DIVIDER, mPageDivider);
bundle.putInt(KEY_START_PAGE, mStartPage);
bundle.putInt(KEY_END_PAGE, mEndPage);
bundle.putInt(KEY_PAGES, mPages);
return bundle;
}
protected Parcelable restoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
mViewTransition.showView(bundle.getInt(KEY_SHOWN_VIEW), false);
mTipView.setText(bundle.getString(KEY_TIP));
mSavedDataId = bundle.getInt(KEY_DATA);
ArrayList<E> newData = null;
EhApplication app = (EhApplication) getContext().getApplicationContext();
if (mSavedDataId != IntIdGenerator.INVALID_ID) {
newData = (ArrayList<E>) app.removeGlobalStuff(mSavedDataId);
mSavedDataId = IntIdGenerator.INVALID_ID;
if (newData != null) {
mData = newData;
}
}
mIdGenerator.setNextId(bundle.getInt(KEY_NEXT_ID));
mPageDivider = bundle.getParcelable(KEY_PAGE_DIVIDER);
mStartPage = bundle.getInt(KEY_START_PAGE);
mEndPage = bundle.getInt(KEY_END_PAGE);
mPages = bundle.getInt(KEY_PAGES);
notifyDataSetChanged();
if (newData == null) {
mPageDivider.clear();
mStartPage = 0;
mEndPage = 0;
mPages = 0;
firstRefresh();
}
return bundle.getParcelable(KEY_SUPER);
} else {
return state;
}
}
}
}
16
Source : GalleryCommentsScene.java
with Apache License 2.0
from duzhaokun123
with Apache License 2.0
from duzhaokun123
public final clreplaced GalleryCommentsScene extends ToolbarScene implements View.OnClickListener, SwipeRefreshLayout.OnRefreshListener {
public static final String TAG = GalleryCommentsScene.clreplaced.getSimpleName();
public static final String KEY_API_UID = "api_uid";
public static final String KEY_API_KEY = "api_key";
public static final String KEY_GID = "gid";
public static final String KEY_TOKEN = "token";
public static final String KEY_COMMENT_LIST = "comment_list";
private static final int TYPE_COMMENT = 0;
private static final int TYPE_MORE = 1;
private static final int TYPE_PROGRESS = 2;
private long mApiUid;
private String mApiKey;
private long mGid;
private String mToken;
@Nullable
private GalleryCommentList mCommentList;
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private FabLayout mFabLayout;
@Nullable
private FloatingActionButton mFab;
@Nullable
private View mEditPanel;
@Nullable
private ImageView mSendImage;
@Nullable
private EditText mEditText;
@Nullable
private CommentAdapter mAdapter;
@Nullable
private ViewTransition mViewTransition;
private SwipeRefreshLayout mRefreshLayout;
private Drawable mSendDrawable;
private Drawable mPencilDrawable;
private long mCommentId;
private boolean mInAnimation = false;
private boolean mShowAllComments = false;
private boolean mRefreshingComments = false;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void handleArgs(Bundle args) {
if (args == null) {
return;
}
mApiUid = args.getLong(KEY_API_UID, -1L);
mApiKey = args.getString(KEY_API_KEY);
mGid = args.getLong(KEY_GID, -1L);
mToken = args.getString(KEY_TOKEN, null);
mCommentList = args.getParcelable(KEY_COMMENT_LIST);
mShowAllComments = mCommentList != null && !mCommentList.hasMore;
}
private void onInit() {
handleArgs(getArguments());
}
private void onRestore(@NonNull Bundle savedInstanceState) {
mApiUid = savedInstanceState.getLong(KEY_API_UID, -1L);
mApiKey = savedInstanceState.getString(KEY_API_KEY);
mGid = savedInstanceState.getLong(KEY_GID, -1L);
mToken = savedInstanceState.getString(KEY_TOKEN, null);
mCommentList = savedInstanceState.getParcelable(KEY_COMMENT_LIST);
mShowAllComments = mCommentList != null && !mCommentList.hasMore;
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(KEY_API_UID, mApiUid);
outState.putString(KEY_API_KEY, mApiKey);
outState.putLong(KEY_GID, mGid);
outState.putString(KEY_TOKEN, mToken);
outState.putParcelable(KEY_COMMENT_LIST, mCommentList);
}
@NonNull
@Override
public View onCreateViewWithToolbar(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_gallery_comments, container, false);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(view, R.id.recycler_view);
TextView tip = (TextView) ViewUtils.$$(view, R.id.tip);
mEditPanel = ViewUtils.$$(view, R.id.edit_panel);
mSendImage = (ImageView) ViewUtils.$$(mEditPanel, R.id.send);
mEditText = (EditText) ViewUtils.$$(mEditPanel, R.id.edit_text);
mFabLayout = (FabLayout) ViewUtils.$$(view, R.id.fab_layout);
mFab = (FloatingActionButton) ViewUtils.$$(view, R.id.fab);
mRefreshLayout = (SwipeRefreshLayout) ViewUtils.$$(view, R.id.refresh_layout);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
view.setWindowInsetsAnimationCallback(new WindowInsetsAnimation.Callback(WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP) {
int startBottomEditPanel = 0;
int startBottomFabLayout = 0;
int endBottomEditPanel = 0;
int endBottomFabLayout = 0;
WindowInsetsAnimation animation;
@Override
public void onPrepare(@NonNull WindowInsetsAnimation animation) {
this.animation = animation;
if (mEditPanel != null) {
startBottomEditPanel = mEditPanel.getPaddingBottom();
}
if (mFabLayout != null) {
startBottomFabLayout = mFabLayout.getPaddingBottom();
}
super.onPrepare(animation);
}
@NonNull
@Override
public WindowInsetsAnimation.Bounds onStart(@NonNull WindowInsetsAnimation animation, @NonNull WindowInsetsAnimation.Bounds bounds) {
this.animation = animation;
if (mEditPanel != null) {
endBottomEditPanel = mEditPanel.getPaddingBottom();
mEditPanel.setTranslationY(-(startBottomEditPanel - endBottomEditPanel));
}
if (mFabLayout != null) {
endBottomFabLayout = mFabLayout.getPaddingBottom();
mFabLayout.setTranslationY(-(startBottomFabLayout - endBottomFabLayout));
}
return bounds;
}
@NonNull
@Override
public WindowInsets onProgress(@NonNull WindowInsets insets, @NonNull List<WindowInsetsAnimation> runningAnimations) {
if (mEditPanel != null) {
int offset = MathUtils.lerp(-(startBottomEditPanel - endBottomEditPanel), 0, animation.getInterpolatedFraction());
mEditPanel.setTranslationY(offset);
}
if (mFabLayout != null) {
int offset = MathUtils.lerp(-(startBottomFabLayout - endBottomFabLayout), 0, animation.getInterpolatedFraction());
mFabLayout.setTranslationY(offset);
}
return insets;
}
@Override
public void onEnd(@NonNull WindowInsetsAnimation animation) {
startBottomEditPanel = 0;
startBottomFabLayout = 0;
endBottomEditPanel = 0;
endBottomFabLayout = 0;
this.animation = null;
if (mEditPanel != null) {
mEditPanel.setTranslationY(0);
}
if (mFabLayout != null) {
mFabLayout.setTranslationY(0);
}
}
});
}
mRefreshLayout.setColorSchemeResources(R.color.loading_indicator_red, R.color.loading_indicator_purple, R.color.loading_indicator_blue, R.color.loading_indicator_cyan, R.color.loading_indicator_green, R.color.loading_indicator_yellow);
mRefreshLayout.setOnRefreshListener(this);
Context context = requireContext();
Resources resources = getResources();
int paddingBottomFab = resources.getDimensionPixelOffset(R.dimen.gallery_padding_bottom_fab);
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.big_sad_pandroid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
mSendDrawable = ContextCompat.getDrawable(context, R.drawable.v_send_dark_x24);
mPencilDrawable = ContextCompat.getDrawable(context, R.drawable.v_pencil_dark_x24);
mAdapter = new CommentAdapter();
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setShowLastDivider(true);
mRecyclerView.addItemDecoration(decoration);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), mRecyclerView.getPaddingBottom() + paddingBottomFab);
// Cancel change animator
RecyclerView.ItemAnimator itemAnimator = mRecyclerView.gereplacedemAnimator();
if (itemAnimator instanceof DefaulreplacedemAnimator) {
((DefaulreplacedemAnimator) itemAnimator).setSupportsChangeAnimations(false);
}
mSendImage.setOnClickListener(this);
mFab.setOnClickListener(this);
addAboveSnackView(mEditPanel);
addAboveSnackView(mFabLayout);
mViewTransition = new ViewTransition(mRecyclerView, tip);
updateView(false);
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
if (null != mEditPanel) {
removeAboveSnackView(mEditPanel);
mEditPanel = null;
}
if (null != mFabLayout) {
removeAboveSnackView(mFabLayout);
mFabLayout = null;
}
mFab = null;
mSendImage = null;
mEditText = null;
mAdapter = null;
mViewTransition = null;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.gallery_comments);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onNavigationClick() {
onBackPressed();
}
private void voteComment(long id, int vote) {
Context context = getContext();
MainActivity activity = getMainActivity();
if (null == context || null == activity) {
return;
}
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_VOTE_COMMENT).setArgs(mApiUid, mApiKey, mGid, mToken, id, vote).setCallback(new VoteCommentListener(context, activity.getStageId(), getTag()));
EhApplication.getEhClient(context).execute(request);
}
@SuppressLint("InflateParams")
public void showVoteStatusDialog(Context context, String voteStatus) {
String[] temp = StringUtils.split(voteStatus, ',');
final int length = temp.length;
final String[] userArray = new String[length];
final String[] voteArray = new String[length];
for (int i = 0; i < length; i++) {
String str = StringUtils.trim(temp[i]);
int index = str.lastIndexOf(' ');
if (index < 0) {
Log.d(TAG, "Something wrong happened about vote state");
userArray[i] = str;
voteArray[i] = "";
} else {
userArray[i] = StringUtils.trim(str.substring(0, index));
voteArray[i] = StringUtils.trim(str.substring(index + 1));
}
}
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(context);
context = builder.getContext();
final LayoutInflater inflater = LayoutInflater.from(context);
EasyRecyclerView rv = (EasyRecyclerView) inflater.inflate(R.layout.dialog_recycler_view, null);
rv.setAdapter(new RecyclerView.Adapter<InfoHolder>() {
@NonNull
@Override
public InfoHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new InfoHolder(inflater.inflate(R.layout.item_drawer_favorites, parent, false));
}
@Override
public void onBindViewHolder(@NonNull InfoHolder holder, int position) {
holder.key.setText(userArray[position]);
holder.value.setText(voteArray[position]);
}
@Override
public int gereplacedemCount() {
return length;
}
});
rv.setLayoutManager(new LinearLayoutManager(context));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setPadding(ResourcesUtils.getAttrDimensionPixelOffset(context, R.attr.dialogPreferredPadding));
rv.addItemDecoration(decoration);
rv.setClipToPadding(false);
builder.setView(rv).show();
}
private void showCommentDialog(int position) {
final Context context = getContext();
if (context == null || mCommentList == null || mCommentList.comments == null || position >= mCommentList.comments.length || position < 0) {
return;
}
final GalleryComment comment = mCommentList.comments[position];
List<String> menu = new ArrayList<>();
final IntList menuId = new IntList();
Resources resources = context.getResources();
menu.add(resources.getString(R.string.copy_comment_text));
menuId.add(R.id.copy);
if (comment.editable) {
menu.add(resources.getString(R.string.edit_comment));
menuId.add(R.id.edit_comment);
}
if (comment.voteUpAble) {
menu.add(resources.getString(comment.voteUpEd ? R.string.cancel_vote_up : R.string.vote_up));
menuId.add(R.id.vote_up);
}
if (comment.voteDownAble) {
menu.add(resources.getString(comment.voteDownEd ? R.string.cancel_vote_down : R.string.vote_down));
menuId.add(R.id.vote_down);
}
if (!TextUtils.isEmpty(comment.voteState)) {
menu.add(resources.getString(R.string.check_vote_status));
menuId.add(R.id.check_vote_status);
}
new MaterialAlertDialogBuilder(context).sereplacedems(menu.toArray(new String[0]), (dialog, which) -> {
if (which < 0 || which >= menuId.size()) {
return;
}
int id = menuId.get(which);
if (id == R.id.copy) {
ClipboardUtil.addTextToClipboard(comment.comment);
showTip(R.string.copied_to_clipboard, LENGTH_SHORT);
} else if (id == R.id.vote_up) {
voteComment(comment.id, 1);
} else if (id == R.id.vote_down) {
voteComment(comment.id, -1);
} else if (id == R.id.check_vote_status) {
showVoteStatusDialog(context, comment.voteState);
} else if (id == R.id.edit_comment) {
prepareEditComment(comment.id);
if (!mInAnimation && mEditPanel != null && mEditPanel.getVisibility() != View.VISIBLE) {
showEditPanel(true);
}
}
}).show();
}
public boolean onItemClick(EasyRecyclerView parent, View view, int position) {
MainActivity activity = getMainActivity();
if (null == activity) {
return false;
}
RecyclerView.ViewHolder holder = parent.getChildViewHolder(view);
if (holder instanceof ActualCommentHolder) {
ActualCommentHolder commentHolder = (ActualCommentHolder) holder;
ClickableSpan span = commentHolder.comment.getCurrentSpan();
commentHolder.comment.clearCurrentSpan();
if (span instanceof URLSpan) {
UrlOpener.openUrl(activity, ((URLSpan) span).getURL(), true);
} else {
showCommentDialog(position);
}
} else if (holder instanceof MoreCommentHolder && !mRefreshingComments && mAdapter != null) {
mRefreshingComments = true;
mShowAllComments = true;
mAdapter.notifyItemChanged(position);
String url = getGalleryDetailUrl();
if (url != null) {
// Request
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_GET_GALLERY_DETAIL).setArgs(url).setCallback(new RefreshCommentListener(activity, activity.getStageId(), getTag()));
EhApplication.getEhClient(activity).execute(request);
}
}
return true;
}
private void updateView(boolean animation) {
if (null == mViewTransition) {
return;
}
if (mCommentList == null || mCommentList.comments == null || mCommentList.comments.length <= 0) {
mViewTransition.showView(1, animation);
} else {
mViewTransition.showView(0, animation);
}
}
private void prepareNewComment() {
mCommentId = 0;
if (mSendImage != null) {
mSendImage.setImageDrawable(mSendDrawable);
}
}
private void prepareEditComment(long commentId) {
mCommentId = commentId;
if (mSendImage != null) {
mSendImage.setImageDrawable(mPencilDrawable);
}
}
private void showEditPanelWithAnimation() {
if (null == mFab || null == mEditPanel) {
return;
}
mInAnimation = true;
mFab.setTranslationX(0.0f);
mFab.setTranslationY(0.0f);
mFab.setScaleX(1.0f);
mFab.setScaleY(1.0f);
int fabEndX = mEditPanel.getLeft() + (mEditPanel.getWidth() / 2) - (mFab.getWidth() / 2);
int fabEndY = mEditPanel.getTop() + (mEditPanel.getHeight() / 2) - (mFab.getHeight() / 2);
mFab.animate().x(fabEndX).y(fabEndY).scaleX(0.0f).scaleY(0.0f).setInterpolator(AnimationUtils.SLOW_FAST_SLOW_INTERPOLATOR).setDuration(300L).setListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
if (null == mFab || null == mEditPanel) {
return;
}
((View) mFab).setVisibility(View.INVISIBLE);
mEditPanel.setVisibility(View.VISIBLE);
int halfW = mEditPanel.getWidth() / 2;
int halfH = mEditPanel.getHeight() / 2;
Animator animator = ViewAnimationUtils.createCircularReveal(mEditPanel, halfW, halfH, 0, (float) Math.hypot(halfW, halfH)).setDuration(300L);
animator.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator a) {
mInAnimation = false;
}
});
animator.start();
}
}).start();
}
private void showEditPanel(boolean animation) {
if (animation) {
showEditPanelWithAnimation();
} else {
if (null == mFab || null == mEditPanel) {
return;
}
((View) mFab).setVisibility(View.INVISIBLE);
mEditPanel.setVisibility(View.VISIBLE);
}
}
private void hideEditPanelWithAnimation() {
if (null == mFab || null == mEditPanel) {
return;
}
mInAnimation = true;
int halfW = mEditPanel.getWidth() / 2;
int halfH = mEditPanel.getHeight() / 2;
Animator animator = ViewAnimationUtils.createCircularReveal(mEditPanel, halfW, halfH, (float) Math.hypot(halfW, halfH), 0.0f).setDuration(300L);
animator.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator a) {
if (null == mFab || null == mEditPanel) {
return;
}
if (Looper.myLooper() != Looper.getMainLooper()) {
// Some devices may run this block in non-UI thread.
// It might be a bug of Android OS.
// Check it here to avoid crash.
return;
}
mEditPanel.setVisibility(View.GONE);
((View) mFab).setVisibility(View.VISIBLE);
int fabStartX = mEditPanel.getLeft() + (mEditPanel.getWidth() / 2) - (mFab.getWidth() / 2);
int fabStartY = mEditPanel.getTop() + (mEditPanel.getHeight() / 2) - (mFab.getHeight() / 2);
mFab.setX(fabStartX);
mFab.setY(fabStartY);
mFab.setScaleX(0.0f);
mFab.setScaleY(0.0f);
mFab.setRotation(-45.0f);
mFab.animate().translationX(0.0f).translationY(0.0f).scaleX(1.0f).scaleY(1.0f).rotation(0.0f).setInterpolator(AnimationUtils.SLOW_FAST_SLOW_INTERPOLATOR).setDuration(300L).setListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
mInAnimation = false;
}
}).start();
}
});
animator.start();
}
private void hideEditPanel(boolean animation) {
hideSoftInput();
if (animation) {
hideEditPanelWithAnimation();
} else {
if (null == mFab || null == mEditPanel) {
return;
}
((View) mFab).setVisibility(View.VISIBLE);
mEditPanel.setVisibility(View.INVISIBLE);
}
}
@Nullable
private String getGalleryDetailUrl() {
if (mGid != -1 && mToken != null) {
return EhUrl.getGalleryDetailUrl(mGid, mToken, 0, mShowAllComments);
} else {
return null;
}
}
@Override
public void onClick(View v) {
Context context = getContext();
MainActivity activity = getMainActivity();
if (null == context || null == activity || null == mEditText) {
return;
}
if (mFab == v) {
if (!mInAnimation) {
prepareNewComment();
showEditPanel(true);
}
} else if (mSendImage == v) {
if (!mInAnimation) {
String comment = mEditText.getText().toString();
if (TextUtils.isEmpty(comment)) {
// Comment is empty
return;
}
String url = getGalleryDetailUrl();
if (url == null) {
return;
}
// Request
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_GET_COMMENT_GALLERY).setArgs(url, comment, mCommentId != 0 ? Long.toString(mCommentId) : null).setCallback(new CommentGalleryListener(context, activity.getStageId(), getTag(), mCommentId));
EhApplication.getEhClient(context).execute(request);
hideSoftInput();
hideEditPanel(true);
}
}
}
@Override
public void onBackPressed() {
if (mInAnimation) {
return;
}
if (null != mEditPanel && mEditPanel.getVisibility() == View.VISIBLE) {
hideEditPanel(true);
} else {
finish();
}
}
private void onRefreshGallerySuccess(GalleryCommentList result) {
if (mAdapter == null) {
return;
}
mRefreshLayout.setRefreshing(false);
mRefreshingComments = false;
mCommentList = result;
mAdapter.notifyDataSetChanged();
updateView(true);
Bundle re = new Bundle();
re.putParcelable(KEY_COMMENT_LIST, result);
setResult(SceneFragment.RESULT_OK, re);
}
private void onRefreshGalleryFailure() {
if (mAdapter == null) {
return;
}
mRefreshLayout.setRefreshing(false);
mRefreshingComments = false;
int position = mAdapter.gereplacedemCount() - 1;
if (position >= 0) {
mAdapter.notifyItemChanged(position);
}
}
private void onCommentGallerySuccess(GalleryCommentList result) {
if (mAdapter == null) {
return;
}
mCommentList = result;
mAdapter.notifyDataSetChanged();
Bundle re = new Bundle();
re.putParcelable(KEY_COMMENT_LIST, result);
setResult(SceneFragment.RESULT_OK, re);
// Remove text
if (mEditText != null) {
mEditText.setText("");
}
updateView(true);
}
private void onVoteCommentSuccess(VoteCommentParser.Result result) {
if (mAdapter == null || mCommentList == null || mCommentList.comments == null) {
return;
}
int position = -1;
for (int i = 0, n = mCommentList.comments.length; i < n; i++) {
GalleryComment comment = mCommentList.comments[i];
if (comment.id == result.id) {
position = i;
break;
}
}
if (-1 == position) {
Log.d(TAG, "Can't find comment with id " + result.id);
return;
}
// Update comment
GalleryComment comment = mCommentList.comments[position];
comment.score = result.score;
if (result.expectVote > 0) {
comment.voteUpEd = 0 != result.vote;
comment.voteDownEd = false;
} else {
comment.voteDownEd = 0 != result.vote;
comment.voteUpEd = false;
}
mAdapter.notifyItemChanged(position);
Bundle re = new Bundle();
re.putParcelable(KEY_COMMENT_LIST, mCommentList);
setResult(SceneFragment.RESULT_OK, re);
}
@Override
public void onRefresh() {
if (!mRefreshingComments && mAdapter != null) {
MainActivity activity = (MainActivity) requireActivity();
mRefreshingComments = true;
String url = getGalleryDetailUrl();
if (url != null) {
// Request
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_GET_GALLERY_DETAIL).setArgs(url).setCallback(new RefreshCommentListener(activity, activity.getStageId(), getTag()));
EhApplication.getEhClient(activity).execute(request);
}
}
}
private static clreplaced RefreshCommentListener extends EhCallback<GalleryCommentsScene, GalleryDetail> {
public RefreshCommentListener(Context context, int stageId, String sceneTag) {
super(context, stageId, sceneTag);
}
@Override
public void onSuccess(GalleryDetail result) {
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onRefreshGallerySuccess(result.comments);
}
}
@Override
public void onFailure(Exception e) {
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onRefreshGalleryFailure();
}
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryCommentsScene;
}
}
private static clreplaced CommentGalleryListener extends EhCallback<GalleryCommentsScene, GalleryCommentList> {
private final long mCommentId;
public CommentGalleryListener(Context context, int stageId, String sceneTag, long commentId) {
super(context, stageId, sceneTag);
mCommentId = commentId;
}
@Override
public void onSuccess(GalleryCommentList result) {
showTip(mCommentId != 0 ? R.string.edit_comment_successfully : R.string.comment_successfully, LENGTH_SHORT);
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onCommentGallerySuccess(result);
}
}
@Override
public void onFailure(Exception e) {
showTip(getContent().getString(mCommentId != 0 ? R.string.edit_comment_failed : R.string.comment_failed) + "\n" + ExceptionUtils.getReadableString(e), LENGTH_LONG);
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryCommentsScene;
}
}
private static clreplaced VoteCommentListener extends EhCallback<GalleryCommentsScene, VoteCommentParser.Result> {
public VoteCommentListener(Context context, int stageId, String sceneTag) {
super(context, stageId, sceneTag);
}
@Override
public void onSuccess(VoteCommentParser.Result result) {
showTip(result.expectVote > 0 ? (0 != result.vote ? R.string.vote_up_successfully : R.string.cancel_vote_up_successfully) : (0 != result.vote ? R.string.vote_down_successfully : R.string.cancel_vote_down_successfully), LENGTH_SHORT);
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onVoteCommentSuccess(result);
}
}
@Override
public void onFailure(Exception e) {
showTip(R.string.vote_failed, LENGTH_LONG);
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryCommentsScene;
}
}
private static clreplaced 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 abstract static clreplaced CommentHolder extends RecyclerView.ViewHolder {
public CommentHolder(LayoutInflater inflater, int resId, ViewGroup parent) {
super(inflater.inflate(resId, parent, false));
}
}
private clreplaced ActualCommentHolder extends CommentHolder {
private final TextView user;
private final TextView time;
private final LinkifyTextView comment;
public ActualCommentHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater, R.layout.item_gallery_comment, parent);
user = itemView.findViewById(R.id.user);
time = itemView.findViewById(R.id.time);
comment = itemView.findViewById(R.id.comment);
}
private CharSequence generateComment(Context context, ObservedTextView textView, GalleryComment comment) {
SpannableStringBuilder ssb = Html.fromHtml(comment.comment, new URLImageGetter(textView, EhApplication.getConaco(context)), null);
if (0 != comment.id && 0 != comment.score) {
int score = comment.score;
String scoreString = score > 0 ? "+" + score : Integer.toString(score);
SpannableString ss = new SpannableString(scoreString);
ss.setSpan(new RelativeSizeSpan(0.8f), 0, scoreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new StyleSpan(Typeface.BOLD), 0, scoreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new ForegroundColorSpan(AttrResources.getAttrColor(context, android.R.attr.textColorSecondary)), 0, scoreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append(" ").append(ss);
}
if (comment.lastEdited != 0) {
String str = context.getString(R.string.last_edited, ReadableTime.getTimeAgo(comment.lastEdited));
SpannableString ss = new SpannableString(str);
ss.setSpan(new RelativeSizeSpan(0.8f), 0, str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new StyleSpan(Typeface.BOLD), 0, str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new ForegroundColorSpan(AttrResources.getAttrColor(context, android.R.attr.textColorSecondary)), 0, str.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append("\n\n").append(ss);
}
LinkifyCompat.addLinks(ssb, Linkify.WEB_URLS);
return ssb;
}
public void bind(GalleryComment value) {
user.setText(value.uploader ? getString(R.string.comment_user_uploader, value.user) : value.user);
user.setOnClickListener(v -> {
ListUrlBuilder lub = new ListUrlBuilder();
lub.setMode(ListUrlBuilder.MODE_UPLOADER);
lub.setKeyword(value.user);
GalleryListScene.startScene(GalleryCommentsScene.this, lub);
});
time.setText(ReadableTime.getTimeAgo(value.time));
comment.setText(generateComment(comment.getContext(), comment, value));
}
}
private static clreplaced MoreCommentHolder extends CommentHolder {
public MoreCommentHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater, R.layout.item_gallery_comment_more, parent);
}
}
private static clreplaced ProgressCommentHolder extends CommentHolder {
public ProgressCommentHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater, R.layout.item_gallery_comment_progress, parent);
}
}
private clreplaced CommentAdapter extends RecyclerView.Adapter<CommentHolder> {
private final LayoutInflater mInflater;
public CommentAdapter() {
mInflater = getLayoutInflater();
replacedertUtils.replacedertNotNull(mInflater);
}
@NonNull
@Override
public CommentHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
switch(viewType) {
case TYPE_COMMENT:
return new ActualCommentHolder(mInflater, parent);
case TYPE_MORE:
return new MoreCommentHolder(mInflater, parent);
case TYPE_PROGRESS:
return new ProgressCommentHolder(mInflater, parent);
default:
throw new IllegalStateException("Invalid view type: " + viewType);
}
}
@Override
public void onBindViewHolder(@NonNull CommentHolder holder, int position) {
Context context = getContext();
if (context == null || mCommentList == null) {
return;
}
holder.itemView.setOnClickListener(v -> onItemClick(mRecyclerView, holder.itemView, position));
holder.itemView.setClickable(true);
holder.itemView.setFocusable(true);
if (holder instanceof ActualCommentHolder) {
((ActualCommentHolder) holder).bind(mCommentList.comments[position]);
}
}
@Override
public int gereplacedemCount() {
if (mCommentList == null || mCommentList.comments == null) {
return 0;
} else if (mCommentList.hasMore) {
return mCommentList.comments.length + 1;
} else {
return mCommentList.comments.length;
}
}
@Override
public int gereplacedemViewType(int position) {
if (position >= mCommentList.comments.length) {
return mRefreshingComments ? TYPE_PROGRESS : TYPE_MORE;
} else {
return TYPE_COMMENT;
}
}
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
Insets insets1 = insets.getInsets(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.ime());
v.setPadding(insets1.left, 0, insets1.right, 0);
View statusBarBackground = v.findViewById(R.id.status_bar_background);
statusBarBackground.getLayoutParams().height = insets1.top;
statusBarBackground.setBackgroundColor(AttrResources.getAttrColor(requireContext(), R.attr.colorPrimaryDark));
if (mFabLayout != null) {
int corner_fab_margin = getResources().getDimensionPixelOffset(R.dimen.corner_fab_margin);
mFabLayout.setPadding(mFabLayout.getPaddingLeft(), mFabLayout.getPaddingTop(), mFabLayout.getPaddingRight(), corner_fab_margin + insets1.bottom);
}
if (mEditPanel != null) {
mEditPanel.setPadding(mEditPanel.getPaddingLeft(), mEditPanel.getPaddingTop(), mEditPanel.getPaddingRight(), insets1.bottom);
}
if (mRecyclerView != null) {
int paddingBottomFab = getResources().getDimensionPixelOffset(R.dimen.gallery_padding_bottom_fab);
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), paddingBottomFab + insets1.bottom);
}
return WindowInsetsCompat.CONSUMED;
}
}
16
Source : GalleryCommentsScene.java
with Apache License 2.0
from duzhaokun123
with Apache License 2.0
from duzhaokun123
public boolean onItemClick(EasyRecyclerView parent, View view, int position) {
MainActivity activity = getMainActivity();
if (null == activity) {
return false;
}
RecyclerView.ViewHolder holder = parent.getChildViewHolder(view);
if (holder instanceof ActualCommentHolder) {
ActualCommentHolder commentHolder = (ActualCommentHolder) holder;
ClickableSpan span = commentHolder.comment.getCurrentSpan();
commentHolder.comment.clearCurrentSpan();
if (span instanceof URLSpan) {
UrlOpener.openUrl(activity, ((URLSpan) span).getURL(), true);
} else {
showCommentDialog(position);
}
} else if (holder instanceof MoreCommentHolder && !mRefreshingComments && mAdapter != null) {
mRefreshingComments = true;
mShowAllComments = true;
mAdapter.notifyItemChanged(position);
String url = getGalleryDetailUrl();
if (url != null) {
// Request
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_GET_GALLERY_DETAIL).setArgs(url).setCallback(new RefreshCommentListener(activity, activity.getStageId(), getTag()));
EhApplication.getEhClient(activity).execute(request);
}
}
return true;
}
16
Source : GalleryCommentsScene.java
with Apache License 2.0
from axlecho
with Apache License 2.0
from axlecho
public final clreplaced GalleryCommentsScene extends ToolbarScene implements EasyRecyclerView.OnItemClickListener, View.OnClickListener {
public static final String TAG = GalleryCommentsScene.clreplaced.getSimpleName();
public static final String KEY_API_UID = "api_uid";
public static final String KEY_API_KEY = "api_key";
public static final String KEY_GID = "gid";
public static final String KEY_TOKEN = "token";
public static final String KEY_COMMENTS = "comments";
private long mApiUid;
private String mApiKey;
private String mGid;
private String mToken;
@Nullable
private GalleryComment[] mComments;
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private FabLayout mFabLayout;
@Nullable
private FloatingActionButton mFab;
@Nullable
private View mEditPanel;
@Nullable
private ImageView mSendImage;
@Nullable
private EditText mEditText;
@Nullable
private CommentAdapter mAdapter;
@Nullable
private ViewTransition mViewTransition;
private boolean mInAnimation = false;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
private void handleArgs(Bundle args) {
if (args == null) {
return;
}
mApiUid = args.getLong(KEY_API_UID, -1L);
mApiKey = args.getString(KEY_API_KEY);
mGid = args.getString(KEY_GID);
mToken = args.getString(KEY_TOKEN, null);
Parcelable[] parcelables = args.getParcelableArray(KEY_COMMENTS);
if (parcelables instanceof GalleryComment[]) {
mComments = (GalleryComment[]) parcelables;
}
}
private void onInit() {
handleArgs(getArguments());
}
private void onRestore(@NonNull Bundle savedInstanceState) {
mApiUid = savedInstanceState.getLong(KEY_API_UID, -1L);
mApiKey = savedInstanceState.getString(KEY_API_KEY);
mGid = savedInstanceState.getString(KEY_GID);
mToken = savedInstanceState.getString(KEY_TOKEN, null);
Parcelable[] parcelables = savedInstanceState.getParcelableArray(KEY_COMMENTS);
if (parcelables instanceof GalleryComment[]) {
mComments = (GalleryComment[]) parcelables;
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong(KEY_API_UID, mApiUid);
outState.putString(KEY_API_KEY, mApiKey);
outState.putString(KEY_GID, mGid);
outState.putString(KEY_TOKEN, mToken);
outState.putParcelableArray(KEY_COMMENTS, mComments);
}
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_gallery_comments, container, false);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(view, R.id.recycler_view);
TextView tip = (TextView) ViewUtils.$$(view, R.id.tip);
mEditPanel = ViewUtils.$$(view, R.id.edit_panel);
mSendImage = (ImageView) ViewUtils.$$(mEditPanel, R.id.send);
mEditText = (EditText) ViewUtils.$$(mEditPanel, R.id.edit_text);
mFabLayout = (FabLayout) ViewUtils.$$(view, R.id.fab_layout);
mFab = (FloatingActionButton) ViewUtils.$$(view, R.id.fab);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
Resources resources = context.getResources();
int paddingBottomFab = resources.getDimensionPixelOffset(R.dimen.gallery_padding_bottom_fab);
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_sad_pandroid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
mAdapter = new CommentAdapter();
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setShowLastDivider(true);
mRecyclerView.addItemDecoration(decoration);
mRecyclerView.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setOnItemClickListener(this);
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), mRecyclerView.getPaddingBottom() + paddingBottomFab);
// Cancel change animator
RecyclerView.ItemAnimator itemAnimator = mRecyclerView.gereplacedemAnimator();
if (itemAnimator instanceof DefaulreplacedemAnimator) {
((DefaulreplacedemAnimator) itemAnimator).setSupportsChangeAnimations(false);
}
mSendImage.setOnClickListener(this);
mFab.setOnClickListener(this);
addAboveSnackView(mEditPanel);
addAboveSnackView(mFabLayout);
mViewTransition = new ViewTransition(mRecyclerView, tip);
updateView(false);
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
if (null != mEditPanel) {
removeAboveSnackView(mEditPanel);
mEditPanel = null;
}
if (null != mFabLayout) {
removeAboveSnackView(mFabLayout);
mFabLayout = null;
}
mFab = null;
mSendImage = null;
mEditText = null;
mAdapter = null;
mViewTransition = null;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setreplacedle(R.string.gallery_comments);
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onNavigationClick() {
onBackPressed();
}
private void voteComment(long id, int vote) {
Context context = getContext2();
MainActivity activity = getActivity2();
if (null == context || null == activity) {
return;
}
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_VOTE_COMMENT).setArgs(mApiUid, mApiKey, mGid, mToken, id, vote).setCallback(new VoteCommentListener(context, activity.getStageId(), getTag()));
EhApplication.getEhClient(context).execute(request);
}
private clreplaced 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);
}
}
@SuppressLint("InflateParams")
public void showVoteStatusDialog(Context context, String voteStatus) {
String[] temp = StringUtils.split(voteStatus, ',');
final int length = temp.length;
final String[] userArray = new String[length];
final String[] voteArray = new String[length];
for (int i = 0; i < length; i++) {
String str = StringUtils.trim(temp[i]);
int index = str.lastIndexOf(' ');
if (index < 0) {
Log.d(TAG, "Something wrong happened about vote state");
userArray[i] = str;
voteArray[i] = "";
} else {
userArray[i] = StringUtils.trim(str.substring(0, index));
voteArray[i] = StringUtils.trim(str.substring(index + 1));
}
}
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 RecyclerView.Adapter<InfoHolder>() {
@Override
public InfoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new InfoHolder(inflater.inflate(R.layout.item_drawer_favorites, parent, false));
}
@Override
public void onBindViewHolder(InfoHolder holder, int position) {
holder.key.setText(userArray[position]);
holder.value.setText(voteArray[position]);
}
@Override
public int gereplacedemCount() {
return length;
}
});
rv.setLayoutManager(new LinearLayoutManager(context));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setPadding(ResourcesUtils.getAttrDimensionPixelOffset(context, R.attr.dialogPreferredPadding));
rv.addItemDecoration(decoration);
rv.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
rv.setClipToPadding(false);
builder.setView(rv).show();
}
private void showCommentDialog(int position) {
final Context context = getContext2();
if (null == context || null == mComments || position >= mComments.length || position < 0) {
return;
}
final GalleryComment comment = mComments[position];
List<String> menu = new ArrayList<>();
final IntList menuId = new IntList();
Resources resources = context.getResources();
if (0 == comment.id || mApiUid < 0) {
// 0 id is uploader comment, can't vote
// Not sign in, can't vote
menu.add(resources.getString(R.string.copy_comment_text));
menuId.add(R.id.copy);
} else {
menu.add(resources.getString(R.string.copy_comment_text));
menuId.add(R.id.copy);
menu.add(resources.getString(comment.voteUp ? R.string.cancel_vote_up : R.string.vote_up));
menuId.add(R.id.vote_up);
menu.add(resources.getString(comment.voteDown ? R.string.cancel_vote_down : R.string.vote_down));
menuId.add(R.id.vote_down);
}
if (!TextUtils.isEmpty(comment.voteState)) {
menu.add(resources.getString(R.string.check_vote_status));
menuId.add(R.id.check_vote_status);
}
new AlertDialog.Builder(context).sereplacedems(menu.toArray(new String[menu.size()]), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which < 0 || which >= menuId.size()) {
return;
}
int id = menuId.get(which);
switch(id) {
case R.id.copy:
ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
cmb.setPrimaryClip(ClipData.newPlainText(null, comment.comment));
showTip(R.string.copied_to_clipboard, LENGTH_SHORT);
break;
case R.id.vote_up:
voteComment(comment.id, 1);
break;
case R.id.vote_down:
voteComment(comment.id, -1);
break;
case R.id.check_vote_status:
showVoteStatusDialog(context, comment.voteState);
break;
}
}
}).show();
}
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
Activity activity = getActivity2();
if (null == activity) {
return false;
}
RecyclerView.ViewHolder holder = parent.getChildViewHolder(view);
if (holder instanceof CommentHolder) {
CommentHolder commentHolder = (CommentHolder) holder;
ClickableSpan span = commentHolder.comment.getCurrentSpan();
commentHolder.comment.clearCurrentSpan();
if (span instanceof URLSpan) {
UrlOpener.openUrl(activity, ((URLSpan) span).getURL(), true);
return true;
}
}
showCommentDialog(position);
return true;
}
private void updateView(boolean animation) {
if (null == mViewTransition) {
return;
}
if (mComments == null || mComments.length <= 0) {
mViewTransition.showView(1, animation);
} else {
mViewTransition.showView(0, animation);
}
}
private void showEditPanelWithAnimation() {
if (null == mFab || null == mEditPanel) {
return;
}
mInAnimation = true;
mFab.setTranslationX(0.0f);
mFab.setTranslationY(0.0f);
mFab.setScaleX(1.0f);
mFab.setScaleY(1.0f);
int fabEndX = mEditPanel.getLeft() + (mEditPanel.getWidth() / 2) - (mFab.getWidth() / 2);
int fabEndY = mEditPanel.getTop() + (mEditPanel.getHeight() / 2) - (mFab.getHeight() / 2);
mFab.animate().x(fabEndX).y(fabEndY).scaleX(0.0f).scaleY(0.0f).setInterpolator(AnimationUtils.SLOW_FAST_SLOW_INTERPOLATOR).setDuration(300L).setListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
if (null == mFab || null == mEditPanel) {
return;
}
((View) mFab).setVisibility(View.INVISIBLE);
mEditPanel.setVisibility(View.VISIBLE);
int halfW = mEditPanel.getWidth() / 2;
int halfH = mEditPanel.getHeight() / 2;
Animator animator = ViewAnimationUtils.createCircularReveal(mEditPanel, halfW, halfH, 0, (float) Math.hypot(halfW, halfH)).setDuration(300L);
animator.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator a) {
mInAnimation = false;
}
});
animator.start();
}
}).start();
}
private void showEditPanel(boolean animation) {
if (animation) {
showEditPanelWithAnimation();
} else {
if (null == mFab || null == mEditPanel) {
return;
}
((View) mFab).setVisibility(View.INVISIBLE);
mEditPanel.setVisibility(View.VISIBLE);
}
}
private void hideEditPanelWithAnimation() {
if (null == mFab || null == mEditPanel) {
return;
}
mInAnimation = true;
int halfW = mEditPanel.getWidth() / 2;
int halfH = mEditPanel.getHeight() / 2;
Animator animator = ViewAnimationUtils.createCircularReveal(mEditPanel, halfW, halfH, (float) Math.hypot(halfW, halfH), 0.0f).setDuration(300L);
animator.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator a) {
if (null == mFab || null == mEditPanel) {
return;
}
if (Looper.myLooper() != Looper.getMainLooper()) {
// Some devices may run this block in non-UI thread.
// It might be a bug of Android OS.
// Check it here to avoid crash.
return;
}
mEditPanel.setVisibility(View.GONE);
((View) mFab).setVisibility(View.VISIBLE);
int fabStartX = mEditPanel.getLeft() + (mEditPanel.getWidth() / 2) - (mFab.getWidth() / 2);
int fabStartY = mEditPanel.getTop() + (mEditPanel.getHeight() / 2) - (mFab.getHeight() / 2);
mFab.setX(fabStartX);
mFab.setY(fabStartY);
mFab.setScaleX(0.0f);
mFab.setScaleY(0.0f);
mFab.setRotation(-45.0f);
mFab.animate().translationX(0.0f).translationY(0.0f).scaleX(1.0f).scaleY(1.0f).rotation(0.0f).setInterpolator(AnimationUtils.SLOW_FAST_SLOW_INTERPOLATOR).setDuration(300L).setListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
mInAnimation = false;
}
}).start();
}
});
animator.start();
}
private void hideEditPanel(boolean animation) {
if (animation) {
hideEditPanelWithAnimation();
} else {
if (null == mFab || null == mEditPanel) {
return;
}
((View) mFab).setVisibility(View.VISIBLE);
mEditPanel.setVisibility(View.INVISIBLE);
}
}
@Nullable
private String getGalleryDetailUrl() {
return MHApi.Companion.getINSTANCE().get(currentSource).pageUrl(mGid);
}
@Override
public void onClick(View v) {
Context context = getContext2();
MainActivity activity = getActivity2();
if (null == context || null == activity || null == mEditText) {
return;
}
if (mFab == v) {
if (!mInAnimation) {
showEditPanel(true);
}
} else if (mSendImage == v) {
if (!mInAnimation) {
String comment = mEditText.getText().toString();
if (TextUtils.isEmpty(comment)) {
// Comment is empty
return;
}
String url = getGalleryDetailUrl();
if (url == null) {
return;
}
// Request
EhRequest request = new EhRequest().setMethod(EhClient.METHOD_GET_COMMENT_GALLERY).setArgs(url, comment).setCallback(new CommentGalleryListener(context, activity.getStageId(), getTag()));
EhApplication.getEhClient(context).execute(request);
hideSoftInput();
hideEditPanel(true);
}
}
}
@Override
public void onBackPressed() {
if (mInAnimation) {
return;
}
if (null != mEditPanel && mEditPanel.getVisibility() == View.VISIBLE) {
hideEditPanel(true);
} else {
finish();
}
}
private clreplaced CommentHolder extends RecyclerView.ViewHolder {
public final TextView user;
public final TextView time;
public final LinkifyTextView comment;
public CommentHolder(View itemView) {
super(itemView);
user = (TextView) itemView.findViewById(R.id.user);
time = (TextView) itemView.findViewById(R.id.time);
comment = (LinkifyTextView) itemView.findViewById(R.id.comment);
}
}
private clreplaced CommentAdapter extends RecyclerView.Adapter<CommentHolder> {
private final LayoutInflater mInflater;
public CommentAdapter() {
mInflater = getLayoutInflater2();
replacedertUtils.replacedertNotNull(mInflater);
}
@Override
public CommentHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new CommentHolder(mInflater.inflate(R.layout.item_gallery_comment, parent, false));
}
public CharSequence generateComment(Context context, ObservedTextView textView, GalleryComment comment) {
SpannableStringBuilder ssb = Html.fromHtml(comment.comment, new URLImageGetter(textView, EhApplication.getConaco(context)), null);
if (0 != comment.id && 0 != comment.score) {
int score = comment.score;
String scoreString = score > 0 ? "+" + score : Integer.toString(score);
SpannableString ss = new SpannableString(scoreString);
ss.setSpan(new RelativeSizeSpan(0.8f), 0, scoreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new StyleSpan(Typeface.BOLD), 0, scoreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ss.setSpan(new ForegroundColorSpan(AttrResources.getAttrColor(context, android.R.attr.textColorSecondary)), 0, scoreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append(" ").append(ss);
}
return TextUrl.handleTextUrl(ssb);
}
@Override
public void onBindViewHolder(CommentHolder holder, int position) {
Context context = getContext2();
if (null == context || null == mComments) {
return;
}
GalleryComment comment = mComments[position];
holder.user.setText(comment.user);
holder.time.setText(comment.time);
holder.comment.setText(generateComment(context, holder.comment, comment));
}
@Override
public int gereplacedemCount() {
return mComments == null ? 0 : mComments.length;
}
}
private void onCommentGallerySuccess(GalleryComment[] result) {
if (null == mAdapter) {
return;
}
mComments = result;
mAdapter.notifyDataSetChanged();
Bundle re = new Bundle();
re.putParcelableArray(KEY_COMMENTS, result);
setResult(SceneFragment.RESULT_OK, re);
// Remove text
if (mEditText != null) {
mEditText.setText("");
}
updateView(true);
}
private void onVoteCommentSuccess(VoteCommentParser.Result result) {
if (null == mAdapter || null == mComments) {
return;
}
int position = -1;
for (int i = 0, n = mComments.length; i < n; i++) {
GalleryComment comment = mComments[i];
if (comment.id == result.id) {
position = i;
break;
}
}
if (-1 == position) {
Log.d(TAG, "Can't find comment with id " + result.id);
return;
}
// Update comment
GalleryComment comment = mComments[position];
comment.score = result.score;
if (result.expectVote > 0) {
comment.voteUp = 0 != result.vote;
comment.voteDown = false;
} else {
comment.voteDown = 0 != result.vote;
comment.voteUp = false;
}
mAdapter.notifyItemChanged(position);
Bundle re = new Bundle();
re.putParcelableArray(KEY_COMMENTS, mComments);
setResult(SceneFragment.RESULT_OK, re);
}
private static clreplaced CommentGalleryListener extends EhCallback<GalleryCommentsScene, GalleryComment[]> {
public CommentGalleryListener(Context context, int stageId, String sceneTag) {
super(context, stageId, sceneTag);
}
@Override
public void onSuccess(GalleryComment[] result) {
showTip(R.string.comment_successfully, LENGTH_SHORT);
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onCommentGallerySuccess(result);
}
}
@Override
public void onFailure(Exception e) {
showTip(getContent().getString(R.string.comment_failed) + "\n" + ExceptionUtils.getReadableString(e), LENGTH_LONG);
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryCommentsScene;
}
}
private static clreplaced VoteCommentListener extends EhCallback<GalleryCommentsScene, VoteCommentParser.Result> {
public VoteCommentListener(Context context, int stageId, String sceneTag) {
super(context, stageId, sceneTag);
}
@Override
public void onSuccess(VoteCommentParser.Result result) {
showTip(result.expectVote > 0 ? (0 != result.vote ? R.string.vote_up_successfully : R.string.cancel_vote_up_successfully) : (0 != result.vote ? R.string.vote_down_successfully : R.string.cancel_vote_down_successfully), LENGTH_SHORT);
GalleryCommentsScene scene = getScene();
if (scene != null) {
scene.onVoteCommentSuccess(result);
}
}
@Override
public void onFailure(Exception e) {
showTip(R.string.vote_failed, LENGTH_LONG);
}
@Override
public void onCancel() {
}
@Override
public boolean isInstance(SceneFragment scene) {
return scene instanceof GalleryCommentsScene;
}
}
@Override
public void loadSource() {
}
}
15
Source : FavoritesScene.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
@Override
@Implemented(EasyRecyclerView.CustomChoiceListener.clreplaced)
public void onIntoCustomChoice(EasyRecyclerView view) {
if (mFabLayout != null) {
showSelectionFabs();
mFabLayout.setAutoCancel(false);
// Delay expanding action to make layout work fine
SimpleHandler.getInstance().post(() -> 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);
}
14
Source : DownloadsScene.java
with Apache License 2.0
from xiaojieonly
with Apache License 2.0
from xiaojieonly
public clreplaced DownloadsScene extends ToolbarScene implements DownloadManager.DownloadInfoListener, EasyRecyclerView.OnItemClickListener, EasyRecyclerView.OnItemLongClickListener, FabLayout.OnClickFabListener, FastScroller.OnDragHandlerListener {
private static final String TAG = DownloadsScene.clreplaced.getSimpleName();
public static final String KEY_GID = "gid";
public static final String KEY_ACTION = "action";
private static final String KEY_LABEL = "label";
public static final String ACTION_CLEAR_DOWNLOAD_SERVICE = "clear_download_service";
/*---------------
Whole life cycle
---------------*/
@Nullable
private DownloadManager mDownloadManager;
@Nullable
private String mLabel;
@Nullable
private List<DownloadInfo> mList;
/*---------------
View life cycle
---------------*/
@Nullable
private EasyRecyclerView mRecyclerView;
@Nullable
private ViewTransition mViewTransition;
@Nullable
private FabLayout mFabLayout;
@Nullable
private DownloadAdapter mAdapter;
@Nullable
private AutoStaggeredGridLayoutManager mLayoutManager;
private ShowcaseView mShowcaseView;
private int mInitPosition = -1;
@Override
public int getNavCheckedItem() {
return R.id.nav_downloads;
}
private boolean handleArguments(Bundle args) {
if (null == args) {
return false;
}
if (ACTION_CLEAR_DOWNLOAD_SERVICE.equals(args.getString(KEY_ACTION))) {
DownloadService.clear();
}
long gid;
if (null != mDownloadManager && -1L != (gid = args.getLong(KEY_GID, -1L))) {
DownloadInfo info = mDownloadManager.getDownloadInfo(gid);
if (null != info) {
mLabel = info.getLabel();
updateForLabel();
updateView();
// Get position
if (null != mList) {
int position = mList.indexOf(info);
if (position >= 0 && null != mRecyclerView) {
mRecyclerView.scrollToPosition(position);
} else {
mInitPosition = position;
}
}
return true;
}
}
return false;
}
@Override
public void onNewArguments(@NonNull Bundle args) {
handleArguments(args);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
mDownloadManager = EhApplication.getDownloadManager(context);
mDownloadManager.addDownloadInfoListener(this);
if (savedInstanceState == null) {
onInit();
} else {
onRestore(savedInstanceState);
}
}
@Override
public void onDestroy() {
super.onDestroy();
mList = null;
DownloadManager manager = mDownloadManager;
if (null == manager) {
Context context = getContext2();
if (null != context) {
manager = EhApplication.getDownloadManager(context);
}
} else {
mDownloadManager = null;
}
if (null != manager) {
manager.removeDownloadInfoListener(this);
} else {
Log.e(TAG, "Can't removeDownloadInfoListener");
}
}
private void updateForLabel() {
if (null == mDownloadManager) {
return;
}
if (mLabel == null) {
mList = mDownloadManager.getDefaultDownloadInfoList();
} else {
mList = mDownloadManager.getLabelDownloadInfoList(mLabel);
if (mList == null) {
mLabel = null;
mList = mDownloadManager.getDefaultDownloadInfoList();
}
}
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
updatereplacedle();
Settings.putRecentDownloadLabel(mLabel);
}
private void updatereplacedle() {
setreplacedle(getString(R.string.scene_download_replacedle, mLabel != null ? mLabel : getString(R.string.default_download_label_name)));
}
private void onInit() {
if (!handleArguments(getArguments())) {
mLabel = Settings.getRecentDownloadLabel();
updateForLabel();
}
}
private void onRestore(@NonNull Bundle savedInstanceState) {
mLabel = savedInstanceState.getString(KEY_LABEL);
updateForLabel();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(KEY_LABEL, mLabel);
}
@Nullable
@Override
public View onCreateView3(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.scene_download, container, false);
View content = ViewUtils.$$(view, R.id.content);
mRecyclerView = (EasyRecyclerView) ViewUtils.$$(content, R.id.recycler_view);
FastScroller fastScroller = (FastScroller) ViewUtils.$$(content, R.id.fast_scroller);
mFabLayout = (FabLayout) ViewUtils.$$(view, R.id.fab_layout);
TextView tip = (TextView) ViewUtils.$$(view, R.id.tip);
mViewTransition = new ViewTransition(content, tip);
Context context = getContext2();
replacedertUtils.replacedertNotNull(content);
Resources resources = context.getResources();
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_download);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
mAdapter = new DownloadAdapter();
mAdapter.setHreplacedtableIds(true);
mRecyclerView.setAdapter(mAdapter);
mLayoutManager = new AutoStaggeredGridLayoutManager(0, StaggeredGridLayoutManager.VERTICAL);
mLayoutManager.setColumnSize(resources.getDimensionPixelOffset(Settings.getDetailSizeResId()));
mLayoutManager.setStrategy(AutoStaggeredGridLayoutManager.STRATEGY_MIN_SIZE);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setSelector(Ripple.generateRippleDrawable(context, !AttrResources.getAttrBoolean(context, R.attr.isLightTheme), new ColorDrawable(Color.TRANSPARENT)));
mRecyclerView.setDrawSelectorOnTop(true);
mRecyclerView.setClipToPadding(false);
mRecyclerView.setOnItemClickListener(this);
mRecyclerView.setOnItemLongClickListener(this);
mRecyclerView.setChoiceMode(EasyRecyclerView.CHOICE_MODE_MULTIPLE_CUSTOM);
mRecyclerView.setCustomCheckedListener(new DownloadChoiceListener());
// Cancel change animation
RecyclerView.ItemAnimator itemAnimator = mRecyclerView.gereplacedemAnimator();
if (itemAnimator instanceof SimpleItemAnimator) {
((SimpleItemAnimator) itemAnimator).setSupportsChangeAnimations(false);
}
int interval = resources.getDimensionPixelOffset(R.dimen.gallery_list_interval);
int paddingH = resources.getDimensionPixelOffset(R.dimen.gallery_list_margin_h);
int paddingV = resources.getDimensionPixelOffset(R.dimen.gallery_list_margin_v);
MarginItemDecoration decoration = new MarginItemDecoration(interval, paddingH, paddingV, paddingH, paddingV);
mRecyclerView.addItemDecoration(decoration);
decoration.applyPaddings(mRecyclerView);
if (mInitPosition >= 0) {
mRecyclerView.scrollToPosition(mInitPosition);
mInitPosition = -1;
}
fastScroller.attachToRecyclerView(mRecyclerView);
HandlerDrawable handlerDrawable = new HandlerDrawable();
handlerDrawable.setColor(AttrResources.getAttrColor(context, R.attr.widgetColorThemeAccent));
fastScroller.setHandlerDrawable(handlerDrawable);
fastScroller.setOnDragHandlerListener(this);
mFabLayout.setExpanded(false, false);
mFabLayout.setHidePrimaryFab(true);
mFabLayout.setAutoCancel(false);
mFabLayout.setOnClickFabListener(this);
addAboveSnackView(mFabLayout);
updateView();
guide();
return view;
}
private void guide() {
if (Settings.getGuideDownloadThumb() && null != mRecyclerView) {
mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Settings.getGuideDownloadThumb()) {
guideDownloadThumb();
}
if (null != mRecyclerView) {
ViewUtils.removeOnGlobalLayoutListener(mRecyclerView.getViewTreeObserver(), this);
}
}
});
} else {
guideDownloadLabels();
}
}
private void guideDownloadThumb() {
MainActivity activity = getActivity2();
if (null == activity || !Settings.getGuideDownloadThumb() || null == mLayoutManager || null == mRecyclerView) {
guideDownloadLabels();
return;
}
int position = mLayoutManager.findFirstCompletelyVisibleItemPositions(null)[0];
if (position < 0) {
guideDownloadLabels();
return;
}
RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(position);
if (null == holder) {
guideDownloadLabels();
return;
}
mShowcaseView = new ShowcaseView.Builder(activity).withMaterialShowcase().setStyle(R.style.Guide).setTarget(new ViewTarget(((DownloadHolder) holder).thumb)).blockAllTouches().setContentreplacedle(R.string.guide_download_thumb_replacedle).setContentText(R.string.guide_download_thumb_text).replaceEndButton(R.layout.button_guide).setShowcaseEventListener(new SimpleShowcaseEventListener() {
@Override
public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
mShowcaseView = null;
ViewUtils.removeFromParent(showcaseView);
Settings.putGuideDownloadThumb(false);
guideDownloadLabels();
}
}).build();
}
private void guideDownloadLabels() {
MainActivity activity = getActivity2();
if (null == activity || !Settings.getGuideDownloadLabels()) {
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().setContentreplacedle(R.string.guide_download_labels_replacedle).setContentText(R.string.guide_download_labels_text).replaceEndButton(R.layout.button_guide).setShowcaseEventListener(new SimpleShowcaseEventListener() {
@Override
public void onShowcaseViewDidHide(ShowcaseView showcaseView) {
mShowcaseView = null;
ViewUtils.removeFromParent(showcaseView);
Settings.puttGuideDownloadLabels(false);
openDrawer(Gravity.RIGHT);
}
}).build();
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
updatereplacedle();
setNavigationIcon(R.drawable.v_arrow_left_dark_x24);
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (null != mShowcaseView) {
ViewUtils.removeFromParent(mShowcaseView);
mShowcaseView = null;
}
if (null != mRecyclerView) {
mRecyclerView.stopScroll();
mRecyclerView = null;
}
if (null != mFabLayout) {
removeAboveSnackView(mFabLayout);
mFabLayout = null;
}
mRecyclerView = null;
mViewTransition = null;
mAdapter = null;
mLayoutManager = null;
}
@Override
public void onNavigationClick() {
onBackPressed();
}
@Override
public int getMenuResId() {
return R.menu.scene_download;
}
@Override
public boolean onMenuItemClick(MenuItem item) {
// Skip when in choice mode
Activity activity = getActivity2();
if (null == activity || null == mRecyclerView || mRecyclerView.isInCustomChoice()) {
return false;
}
int id = item.gereplacedemId();
switch(id) {
case R.id.action_start_all:
{
Intent intent = new Intent(activity, DownloadService.clreplaced);
intent.setAction(DownloadService.ACTION_START_ALL);
activity.startService(intent);
return true;
}
case R.id.action_stop_all:
{
if (null != mDownloadManager) {
mDownloadManager.stopAllDownload();
}
return true;
}
case R.id.action_reset_reading_progress:
{
new AlertDialog.Builder(getContext()).setMessage(R.string.reset_reading_progress_message).setNegativeButton(android.R.string.cancel, null).setPositiveButton(android.R.string.ok, (dialog, which) -> {
if (mDownloadManager != null) {
mDownloadManager.resetAllReadingProgress();
}
}).show();
return true;
}
}
return false;
}
public void updateView() {
if (mViewTransition != null) {
if (mList == null || mList.size() == 0) {
mViewTransition.showView(1);
} else {
mViewTransition.showView(0);
}
}
}
@Override
public View onCreateDrawerView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.drawer_list, container, false);
final Context context = getContext2();
replacedertUtils.replacedertNotNull(context);
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
toolbar.setreplacedle(R.string.download_labels);
toolbar.inflateMenu(R.menu.drawer_download);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
int id = item.gereplacedemId();
switch(id) {
case R.id.action_settings:
startScene(new Announcer(DownloadLabelsScene.clreplaced));
return true;
case R.id.action_default_download_label:
DownloadManager dm = mDownloadManager;
if (null == dm) {
return true;
}
List<DownloadLabel> list = dm.getLabelList();
final String[] items = new String[list.size() + 2];
items[0] = getString(R.string.let_me_select);
items[1] = getString(R.string.default_download_label_name);
for (int i = 0, n = list.size(); i < n; i++) {
items[i + 2] = list.get(i).getLabel();
}
new AlertDialog.Builder(context).setreplacedle(R.string.default_download_label).sereplacedems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
Settings.putHasDefaultDownloadLabel(false);
} else {
Settings.putHasDefaultDownloadLabel(true);
String label;
if (which == 1) {
label = null;
} else {
label = items[which];
}
Settings.putDefaultDownloadLabel(label);
}
}
}).show();
return true;
}
return false;
}
});
List<DownloadLabel> list = EhApplication.getDownloadManager(context).getLabelList();
final List<String> labels = new ArrayList<>(list.size() + 1);
// Add default label name
labels.add(getString(R.string.default_download_label_name));
for (DownloadLabel raw : list) {
labels.add(raw.getLabel());
}
// TODO handle download label items update
ListView listView = (ListView) view.findViewById(R.id.list_view);
listView.setAdapter(new ArrayAdapter<>(context, R.layout.item_simple_list, labels));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String label;
if (position == 0) {
label = null;
} else {
label = labels.get(position);
}
if (!ObjectUtils.equal(label, mLabel)) {
mLabel = label;
updateForLabel();
updateView();
closeDrawer(Gravity.RIGHT);
}
}
});
return view;
}
@Override
public void onBackPressed() {
if (null != mShowcaseView) {
return;
}
if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) {
mRecyclerView.outOfCustomChoiceMode();
} else {
super.onBackPressed();
}
}
@Override
public void onStartDragHandler() {
// Lock right drawer
setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.RIGHT);
}
@Override
public void onEndDragHandler() {
// Restore right drawer
if (null != mRecyclerView && !mRecyclerView.isInCustomChoice()) {
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.RIGHT);
}
}
@Override
public boolean onItemClick(EasyRecyclerView parent, View view, int position, long id) {
Activity activity = getActivity2();
EasyRecyclerView recyclerView = mRecyclerView;
if (null == activity || null == recyclerView) {
return false;
}
if (recyclerView.isInCustomChoice()) {
recyclerView.toggleItemChecked(position);
return true;
} else {
List<DownloadInfo> list = mList;
if (list == null) {
return false;
}
if (position < 0 || position >= list.size()) {
return false;
}
Intent intent = new Intent(activity, GalleryActivity.clreplaced);
intent.setAction(GalleryActivity.ACTION_EH);
intent.putExtra(GalleryActivity.KEY_GALLERY_INFO, list.get(position));
startActivity(intent);
return true;
}
}
@Override
public boolean onItemLongClick(EasyRecyclerView parent, View view, int position, long id) {
EasyRecyclerView recyclerView = mRecyclerView;
if (recyclerView == null) {
return false;
}
if (!recyclerView.isInCustomChoice()) {
recyclerView.intoCustomChoiceMode();
}
recyclerView.toggleItemChecked(position);
return true;
}
@Override
public void onClickPrimaryFab(FabLayout view, FloatingActionButton fab) {
if (mRecyclerView != null && mRecyclerView.isInCustomChoice()) {
mRecyclerView.outOfCustomChoiceMode();
}
}
@Override
public void onClickSecondaryFab(FabLayout view, FloatingActionButton fab, int position) {
Context context = getContext2();
Activity activity = getActivity2();
EasyRecyclerView recyclerView = mRecyclerView;
if (null == context || null == activity || null == recyclerView) {
return;
}
if (0 == position) {
recyclerView.checkAll();
} else {
List<DownloadInfo> list = mList;
if (list == null) {
return;
}
LongList gidList = null;
List<DownloadInfo> downloadInfoList = null;
// Start, Stop, Delete
boolean collectGid = position == 1 || position == 2 || position == 3;
// Delete or Move
boolean collectDownloadInfo = position == 3 || position == 4;
if (collectGid) {
gidList = new LongList();
}
if (collectDownloadInfo) {
downloadInfoList = new LinkedList<>();
}
SparseBooleanArray stateArray = recyclerView.getCheckedItemPositions();
for (int i = 0, n = stateArray.size(); i < n; i++) {
if (stateArray.valueAt(i)) {
DownloadInfo info = list.get(stateArray.keyAt(i));
if (collectDownloadInfo) {
downloadInfoList.add(info);
}
if (collectGid) {
gidList.add(info.gid);
}
}
}
switch(position) {
case 1:
{
// Start
Intent intent = new Intent(activity, DownloadService.clreplaced);
intent.setAction(DownloadService.ACTION_START_RANGE);
intent.putExtra(DownloadService.KEY_GID_LIST, gidList);
activity.startService(intent);
// Cancel check mode
recyclerView.outOfCustomChoiceMode();
break;
}
case 2:
{
// Stop
if (null != mDownloadManager) {
mDownloadManager.stopRangeDownload(gidList);
}
// Cancel check mode
recyclerView.outOfCustomChoiceMode();
break;
}
case 3:
{
// Delete
CheckBoxDialogBuilder builder = new CheckBoxDialogBuilder(context, getString(R.string.download_remove_dialog_message_2, gidList.size()), getString(R.string.download_remove_dialog_check_text), Settings.getRemoveImageFiles());
DeleteRangeDialogHelper helper = new DeleteRangeDialogHelper(downloadInfoList, gidList, builder);
builder.setreplacedle(R.string.download_remove_dialog_replacedle).setPositiveButton(android.R.string.ok, helper).show();
break;
}
case 4:
{
// Move
List<DownloadLabel> labelRawList = EhApplication.getDownloadManager(context).getLabelList();
List<String> labelList = new ArrayList<>(labelRawList.size() + 1);
labelList.add(getString(R.string.default_download_label_name));
for (int i = 0, n = labelRawList.size(); i < n; i++) {
labelList.add(labelRawList.get(i).getLabel());
}
String[] labels = labelList.toArray(new String[labelList.size()]);
MoveDialogHelper helper = new MoveDialogHelper(labels, downloadInfoList);
new AlertDialog.Builder(context).setreplacedle(R.string.download_move_dialog_replacedle).sereplacedems(labels, helper).show();
break;
}
}
}
}
@Override
public void onAdd(@NonNull DownloadInfo info, @NonNull List<DownloadInfo> list, int position) {
if (mList != list) {
return;
}
if (mAdapter != null) {
mAdapter.notifyItemInserted(position);
}
updateView();
}
@Override
public void onUpdate(@NonNull DownloadInfo info, @NonNull List<DownloadInfo> list) {
if (mList != list) {
return;
}
int index = list.indexOf(info);
if (index >= 0 && mAdapter != null) {
mAdapter.notifyItemChanged(index);
}
}
@Override
public void onUpdateAll() {
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
}
@Override
public void onReload() {
if (mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
updateView();
}
@Override
public void onChange() {
mLabel = null;
updateForLabel();
updateView();
}
@Override
public void onRenameLabel(String from, String to) {
if (!ObjectUtils.equal(mLabel, from)) {
return;
}
mLabel = to;
updateForLabel();
updateView();
}
@Override
public void onRemove(@NonNull DownloadInfo info, @NonNull List<DownloadInfo> list, int position) {
if (mList != list) {
return;
}
if (mAdapter != null) {
mAdapter.notifyItemRemoved(position);
}
updateView();
}
@Override
public void onUpdateLabels() {
// TODO
}
private void bindForState(DownloadHolder holder, DownloadInfo info) {
Resources resources = getResources2();
if (null == resources) {
return;
}
switch(info.state) {
case DownloadInfo.STATE_NONE:
bindState(holder, info, resources.getString(R.string.download_state_none));
break;
case DownloadInfo.STATE_WAIT:
bindState(holder, info, resources.getString(R.string.download_state_wait));
break;
case DownloadInfo.STATE_DOWNLOAD:
bindProgress(holder, info);
break;
case DownloadInfo.STATE_FAILED:
String text;
if (info.legacy <= 0) {
text = resources.getString(R.string.download_state_failed);
} else {
text = resources.getString(R.string.download_state_failed_2, info.legacy);
}
bindState(holder, info, text);
break;
case DownloadInfo.STATE_FINISH:
bindState(holder, info, resources.getString(R.string.download_state_finish));
break;
}
}
private void bindState(DownloadHolder holder, DownloadInfo info, String state) {
holder.uploader.setVisibility(View.VISIBLE);
holder.rating.setVisibility(View.VISIBLE);
holder.category.setVisibility(View.VISIBLE);
holder.state.setVisibility(View.VISIBLE);
holder.progressBar.setVisibility(View.GONE);
holder.percent.setVisibility(View.GONE);
holder.speed.setVisibility(View.GONE);
if (info.state == DownloadInfo.STATE_WAIT || info.state == DownloadInfo.STATE_DOWNLOAD) {
holder.start.setVisibility(View.GONE);
holder.stop.setVisibility(View.VISIBLE);
} else {
holder.start.setVisibility(View.VISIBLE);
holder.stop.setVisibility(View.GONE);
}
holder.state.setText(state);
}
@SuppressLint("SetTextI18n")
private void bindProgress(DownloadHolder holder, DownloadInfo info) {
holder.uploader.setVisibility(View.GONE);
holder.rating.setVisibility(View.GONE);
holder.category.setVisibility(View.GONE);
holder.state.setVisibility(View.GONE);
holder.progressBar.setVisibility(View.VISIBLE);
holder.percent.setVisibility(View.VISIBLE);
holder.speed.setVisibility(View.VISIBLE);
if (info.state == DownloadInfo.STATE_WAIT || info.state == DownloadInfo.STATE_DOWNLOAD) {
holder.start.setVisibility(View.GONE);
holder.stop.setVisibility(View.VISIBLE);
} else {
holder.start.setVisibility(View.VISIBLE);
holder.stop.setVisibility(View.GONE);
}
if (info.total <= 0 || info.finished < 0) {
holder.percent.setText(null);
holder.progressBar.setIndeterminate(true);
} else {
holder.percent.setText(info.finished + "/" + info.total);
holder.progressBar.setIndeterminate(false);
holder.progressBar.setMax(info.total);
holder.progressBar.setProgress(info.finished);
}
long speed = info.speed;
if (speed < 0) {
speed = 0;
}
holder.speed.setText(FileUtils.humanReadableByteCount(speed, false) + "/S");
}
private static void deleteFileAsync(UniFile... files) {
new AsyncTask<UniFile, Void, Void>() {
@Override
protected Void doInBackground(UniFile... params) {
for (UniFile file : params) {
if (file != null) {
file.delete();
}
}
return null;
}
}.executeOnExecutor(IoThreadPoolExecutor.getInstance(), files);
}
private clreplaced DeleteDialogHelper implements DialogInterface.OnClickListener {
private final GalleryInfo mGalleryInfo;
private final CheckBoxDialogBuilder mBuilder;
public DeleteDialogHelper(GalleryInfo galleryInfo, CheckBoxDialogBuilder builder) {
mGalleryInfo = galleryInfo;
mBuilder = builder;
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which != DialogInterface.BUTTON_POSITIVE) {
return;
}
// Delete
if (null != mDownloadManager) {
mDownloadManager.deleteDownload(mGalleryInfo.gid);
}
// Delete image files
boolean checked = mBuilder.isChecked();
Settings.putRemoveImageFiles(checked);
if (checked) {
// Remove download path
EhDB.removeDownloadDirname(mGalleryInfo.gid);
// Delete file
UniFile file = SpiderDen.getGalleryDownloadDir(mGalleryInfo);
deleteFileAsync(file);
}
}
}
private clreplaced DeleteRangeDialogHelper implements DialogInterface.OnClickListener {
private final List<DownloadInfo> mDownloadInfoList;
private final LongList mGidList;
private final CheckBoxDialogBuilder mBuilder;
public DeleteRangeDialogHelper(List<DownloadInfo> downloadInfoList, LongList gidList, CheckBoxDialogBuilder builder) {
mDownloadInfoList = downloadInfoList;
mGidList = gidList;
mBuilder = builder;
}
@Override
public void onClick(DialogInterface dialog, int which) {
if (which != DialogInterface.BUTTON_POSITIVE) {
return;
}
// Cancel check mode
if (mRecyclerView != null) {
mRecyclerView.outOfCustomChoiceMode();
}
// Delete
if (null != mDownloadManager) {
mDownloadManager.deleteRangeDownload(mGidList);
}
// Delete image files
boolean checked = mBuilder.isChecked();
Settings.putRemoveImageFiles(checked);
if (checked) {
UniFile[] files = new UniFile[mDownloadInfoList.size()];
int i = 0;
for (DownloadInfo info : mDownloadInfoList) {
// Remove download path
EhDB.removeDownloadDirname(info.gid);
// Put file
files[i] = SpiderDen.getGalleryDownloadDir(info);
i++;
}
// Delete file
deleteFileAsync(files);
}
}
}
private clreplaced MoveDialogHelper implements DialogInterface.OnClickListener {
private final String[] mLabels;
private final List<DownloadInfo> mDownloadInfoList;
public MoveDialogHelper(String[] labels, List<DownloadInfo> downloadInfoList) {
mLabels = labels;
mDownloadInfoList = downloadInfoList;
}
@Override
public void onClick(DialogInterface dialog, int which) {
// Cancel check mode
Context context = getContext2();
if (null == context) {
return;
}
if (null != mRecyclerView) {
mRecyclerView.outOfCustomChoiceMode();
}
String label;
if (which == 0) {
label = null;
} else {
label = mLabels[which];
}
EhApplication.getDownloadManager(context).changeLabel(mDownloadInfoList, label);
}
}
private clreplaced DownloadHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final LoadImageView thumb;
public final TextView replacedle;
public final TextView uploader;
public final SimpleRatingView rating;
public final TextView category;
public final View start;
public final View stop;
public final TextView state;
public final ProgressBar progressBar;
public final TextView percent;
public final TextView speed;
public DownloadHolder(View itemView) {
super(itemView);
thumb = (LoadImageView) itemView.findViewById(R.id.thumb);
replacedle = (TextView) itemView.findViewById(R.id.replacedle);
uploader = (TextView) itemView.findViewById(R.id.uploader);
rating = (SimpleRatingView) itemView.findViewById(R.id.rating);
category = (TextView) itemView.findViewById(R.id.category);
start = itemView.findViewById(R.id.start);
stop = itemView.findViewById(R.id.stop);
state = (TextView) itemView.findViewById(R.id.state);
progressBar = (ProgressBar) itemView.findViewById(R.id.progress_bar);
percent = (TextView) itemView.findViewById(R.id.percent);
speed = (TextView) itemView.findViewById(R.id.speed);
// TODO cancel on click listener when select items
thumb.setOnClickListener(this);
start.setOnClickListener(this);
stop.setOnClickListener(this);
boolean isDarkTheme = !AttrResources.getAttrBoolean(getContext2(), R.attr.isLightTheme);
Ripple.addRipple(start, isDarkTheme);
Ripple.addRipple(stop, isDarkTheme);
}
@Override
public void onClick(View v) {
Context context = getContext2();
Activity activity = getActivity2();
EasyRecyclerView recyclerView = mRecyclerView;
if (null == context || null == activity || null == recyclerView || recyclerView.isInCustomChoice()) {
return;
}
List<DownloadInfo> list = mList;
if (list == null) {
return;
}
int size = list.size();
int index = recyclerView.getChildAdapterPosition(itemView);
if (index < 0 || index >= size) {
return;
}
if (thumb == v) {
Bundle args = new Bundle();
args.putString(GalleryDetailScene.KEY_ACTION, GalleryDetailScene.ACTION_GALLERY_INFO);
args.putParcelable(GalleryDetailScene.KEY_GALLERY_INFO, list.get(index));
Announcer announcer = new Announcer(GalleryDetailScene.clreplaced).setArgs(args);
announcer.setTranHelper(new EnterGalleryDetailTransaction(thumb));
startScene(announcer);
} else if (start == v) {
Intent intent = new Intent(activity, DownloadService.clreplaced);
intent.setAction(DownloadService.ACTION_START);
intent.putExtra(DownloadService.KEY_GALLERY_INFO, list.get(index));
activity.startService(intent);
} else if (stop == v) {
if (null != mDownloadManager) {
mDownloadManager.stopDownload(list.get(index).gid);
}
}
}
}
private clreplaced DownloadAdapter extends RecyclerView.Adapter<DownloadHolder> {
private final LayoutInflater mInflater;
private final int mListThumbWidth;
private final int mListThumbHeight;
public DownloadAdapter() {
mInflater = getLayoutInflater2();
replacedertUtils.replacedertNotNull(mInflater);
View calculator = mInflater.inflate(R.layout.item_gallery_list_thumb_height, null);
ViewUtils.measureView(calculator, 1024, ViewGroup.LayoutParams.WRAP_CONTENT);
mListThumbHeight = calculator.getMeasuredHeight();
mListThumbWidth = mListThumbHeight * 2 / 3;
}
@Override
public long gereplacedemId(int position) {
if (mList == null || position < 0 || position >= mList.size()) {
return 0;
}
return mList.get(position).gid;
}
@Override
public DownloadHolder onCreateViewHolder(ViewGroup parent, int viewType) {
DownloadHolder holder = new DownloadHolder(mInflater.inflate(R.layout.item_download, parent, false));
ViewGroup.LayoutParams lp = holder.thumb.getLayoutParams();
lp.width = mListThumbWidth;
lp.height = mListThumbHeight;
holder.thumb.setLayoutParams(lp);
return holder;
}
@Override
public void onBindViewHolder(DownloadHolder holder, int position) {
if (mList == null) {
return;
}
DownloadInfo info = mList.get(position);
holder.thumb.load(EhCacheKeyFactory.getThumbKey(info.gid), info.thumb, new ThumbDataContainer(info), true);
holder.replacedle.setText(EhUtils.getSuitablereplacedle(info));
holder.uploader.setText(info.uploader);
holder.rating.setRating(info.rating);
TextView category = holder.category;
String newCategoryText = EhUtils.getCategory(info.category);
if (!newCategoryText.equals(category.getText())) {
category.setText(newCategoryText);
category.setBackgroundColor(EhUtils.getCategoryColor(info.category));
}
bindForState(holder, info);
// Update transition name
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ViewCompat.setTransitionName(holder.thumb, TransitionNameFactory.getThumbTransitionName(info.gid));
}
}
@Override
public int gereplacedemCount() {
return mList == null ? 0 : mList.size();
}
}
private clreplaced DownloadChoiceListener implements EasyRecyclerView.CustomChoiceListener {
@Override
public void onIntoCustomChoice(EasyRecyclerView view) {
if (mRecyclerView != null) {
mRecyclerView.setOnItemLongClickListener(null);
mRecyclerView.setLongClickable(false);
}
if (mFabLayout != null) {
mFabLayout.setExpanded(true);
}
// Lock drawer
setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.LEFT);
setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.RIGHT);
}
@Override
public void onOutOfCustomChoice(EasyRecyclerView view) {
if (mRecyclerView != null) {
mRecyclerView.setOnItemLongClickListener(DownloadsScene.this);
}
if (mFabLayout != null) {
mFabLayout.setExpanded(false);
}
// Unlock drawer
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.LEFT);
setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.RIGHT);
}
@Override
public void onItemCheckedStateChanged(EasyRecyclerView view, int position, long id, boolean checked) {
if (view.getCheckedItemCount() == 0) {
view.outOfCustomChoiceMode();
}
}
}
private clreplaced ThumbDataContainer implements DataContainer {
private final DownloadInfo mInfo;
@Nullable
private UniFile mFile;
public ThumbDataContainer(@NonNull DownloadInfo info) {
mInfo = info;
}
private void ensureFile() {
if (mFile == null) {
UniFile dir = SpiderDen.getGalleryDownloadDir(mInfo);
if (dir != null && dir.isDirectory()) {
mFile = dir.createFile(".thumb");
}
}
}
@Override
public boolean isEnabled() {
ensureFile();
return mFile != null;
}
@Override
public void onUrlMoved(String requestUrl, String responseUrl) {
}
@Override
public boolean save(InputStream is, long length, String mediaType, ProgressNotifier notify) {
ensureFile();
if (mFile == null) {
return false;
}
OutputStream os = null;
try {
os = mFile.openOutputStream();
IOUtils.copy(is, os);
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
IOUtils.closeQuietly(os);
}
}
@Override
public InputStreamPipe get() {
ensureFile();
if (mFile != null) {
return new UniFileInputStreamPipe(mFile);
} else {
return null;
}
}
@Override
public void remove() {
if (mFile != null) {
mFile.delete();
}
}
}
}
14
Source : SearchBar.java
with Apache License 2.0
from NuclearVGA
with Apache License 2.0
from NuclearVGA
public clreplaced SearchBar extends MaterialCardView implements View.OnClickListener, TextView.OnEditorActionListener, Texreplacedcher, SearchEditText.SearchEditTextListener {
public static final int STATE_NORMAL = 0;
public static final int STATE_SEARCH = 1;
public static final int STATE_SEARCH_LIST = 2;
private static final String STATE_KEY_SUPER = "super";
private static final String STATE_KEY_STATE = "state";
private static final long ANIMATE_TIME = 300L;
private final Rect mRect = new Rect();
private int mState = STATE_NORMAL;
private int mWidth;
private int mHeight;
private int mBaseHeight;
private float mProgress;
private ImageView mMenuButton;
private TextView mreplacedleTextView;
private ImageView mActionButton;
private SearchEditText mEditText;
private EasyRecyclerView mListView;
private View mListContainer;
private ViewTransition mViewTransition;
private SearchDatabase mSearchDatabase;
private List<Suggestion> mSuggestionList;
private SuggestionAdapter mSuggestionAdapter;
private Helper mHelper;
private OnStateChangeListener mOnStateChangeListener;
private SuggestionProvider mSuggestionProvider;
private boolean mAllowEmptySearch = true;
private boolean mInAnimation;
public SearchBar(Context context) {
super(context);
init(context);
}
public SearchBar(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SearchBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
mSearchDatabase = SearchDatabase.getInstance(getContext());
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.widget_search_bar, this);
mMenuButton = (ImageView) ViewUtils.$$(this, R.id.search_menu);
mreplacedleTextView = (TextView) ViewUtils.$$(this, R.id.search_replacedle);
mActionButton = (ImageView) ViewUtils.$$(this, R.id.search_action);
mEditText = (SearchEditText) ViewUtils.$$(this, R.id.search_edit_text);
mListContainer = ViewUtils.$$(this, R.id.list_container);
mListView = (EasyRecyclerView) ViewUtils.$$(mListContainer, R.id.search_bar_list);
mViewTransition = new ViewTransition(mreplacedleTextView, mEditText);
mreplacedleTextView.setOnClickListener(this);
mMenuButton.setOnClickListener(this);
mActionButton.setOnClickListener(this);
mEditText.setSearchEditTextListener(this);
mEditText.setOnEditorActionListener(this);
mEditText.addTextChangedListener(this);
// Get base height
ViewUtils.measureView(this, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
mBaseHeight = getMeasuredHeight();
mSuggestionList = new ArrayList<>();
mSuggestionAdapter = new SuggestionAdapter(LayoutInflater.from(getContext()));
mListView.setAdapter(mSuggestionAdapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(context);
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(LinearDividerItemDecoration.VERTICAL, AttrResources.getAttrColor(context, R.attr.dividerColor), LayoutUtils.dp2pix(context, 1));
decoration.setShowFirstDivider(true);
decoration.setShowLastDivider(false);
mListView.addItemDecoration(decoration);
mListView.setLayoutManager(layoutManager);
}
private void updateSuggestions() {
updateSuggestions(true);
}
private void updateSuggestions(boolean scrollToTop) {
mSuggestionList.clear();
String text = mEditText.getText().toString();
if (mSuggestionProvider != null) {
List<Suggestion> suggestions = mSuggestionProvider.providerSuggestions(text);
if (suggestions != null && !suggestions.isEmpty()) {
mSuggestionList.addAll(suggestions);
}
}
String[] keywords = mSearchDatabase.getSuggestions(text, 128);
for (String keyword : keywords) {
mSuggestionList.add(new KeywordSuggestion(keyword));
}
EhTagDatabase ehTagDatabase = EhTagDatabase.getInstance(getContext());
if (!TextUtils.isEmpty(text) && ehTagDatabase != null && !text.endsWith(" ")) {
String[] s = text.split(" ");
if (s.length > 0) {
String keyword = s[s.length - 1];
ArrayList<Pair<String, String>> searchHints = ehTagDatabase.suggest(keyword);
for (Pair<String, String> searchHint : searchHints) {
mSuggestionList.add(new TagSuggestion(searchHint.first, searchHint.second));
}
}
}
mSuggestionAdapter.notifyDataSetChanged();
if (scrollToTop) {
mListView.scrollToPosition(0);
}
}
public void setAllowEmptySearch(boolean allowEmptySearch) {
mAllowEmptySearch = allowEmptySearch;
}
public void setEditTextHint(CharSequence hint) {
mEditText.setHint(hint);
}
public void setHelper(Helper helper) {
mHelper = helper;
}
public void setOnStateChangeListener(OnStateChangeListener listener) {
mOnStateChangeListener = listener;
}
public void setSuggestionProvider(SuggestionProvider suggestionProvider) {
mSuggestionProvider = suggestionProvider;
}
public String getText() {
return mEditText.getText().toString();
}
public void setText(String text) {
mEditText.setText(text);
}
public void cursorToEnd() {
mEditText.setSelection(mEditText.getText().length());
}
public void setreplacedle(String replacedle) {
mreplacedleTextView.setText(replacedle);
}
public void setSearch(String search) {
mreplacedleTextView.setText(search);
mEditText.setText(search);
}
public void setLeftDrawable(Drawable drawable) {
mMenuButton.setImageDrawable(drawable);
}
public void setRightDrawable(Drawable drawable) {
mActionButton.setImageDrawable(drawable);
}
public void applySearch() {
String query = mEditText.getText().toString().trim();
if (!mAllowEmptySearch && TextUtils.isEmpty(query)) {
return;
}
// Put it into db
mSearchDatabase.addQuery(query);
// Callback
mHelper.onApplySearch(query);
}
@Override
public void onClick(View v) {
if (v == mreplacedleTextView) {
mHelper.onClickreplacedle();
} else if (v == mMenuButton) {
mHelper.onClickLeftIcon();
} else if (v == mActionButton) {
mHelper.onClickRightIcon();
}
}
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (v == mEditText) {
if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_NULL) {
applySearch();
return true;
}
}
return false;
}
public int getState() {
return mState;
}
public void setState(int state) {
setState(state, true);
}
public void setState(int state, boolean animation) {
if (mState != state) {
int oldState = mState;
mState = state;
switch(oldState) {
default:
case STATE_NORMAL:
mViewTransition.showView(1, animation);
mEditText.requestFocus();
if (state == STATE_SEARCH_LIST) {
showImeAndSuggestionsList(animation);
}
if (mOnStateChangeListener != null) {
mOnStateChangeListener.onStateChange(this, state, oldState, animation);
}
break;
case STATE_SEARCH:
if (state == STATE_NORMAL) {
mViewTransition.showView(0, animation);
} else if (state == STATE_SEARCH_LIST) {
showImeAndSuggestionsList(animation);
}
if (mOnStateChangeListener != null) {
mOnStateChangeListener.onStateChange(this, state, oldState, animation);
}
break;
case STATE_SEARCH_LIST:
hideImeAndSuggestionsList(animation);
if (state == STATE_NORMAL) {
mViewTransition.showView(0, animation);
}
if (mOnStateChangeListener != null) {
mOnStateChangeListener.onStateChange(this, state, oldState, animation);
}
break;
}
}
}
public void showImeAndSuggestionsList(boolean animation) {
// Show ime
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(mEditText, 0);
// update suggestion for show suggestions list
updateSuggestions();
// Show suggestions list
if (animation) {
ObjectAnimator oa = ObjectAnimator.ofFloat(this, "progress", 1f);
oa.setDuration(ANIMATE_TIME);
oa.setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR);
oa.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
mListContainer.setVisibility(View.VISIBLE);
mInAnimation = true;
}
@Override
public void onAnimationEnd(Animator animation) {
mInAnimation = false;
}
});
oa.setAutoCancel(true);
oa.start();
} else {
mListContainer.setVisibility(View.VISIBLE);
setProgress(1f);
}
}
private void hideImeAndSuggestionsList(boolean animation) {
// Hide ime
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(this.getWindowToken(), 0);
// Hide suggestions list
if (animation) {
ObjectAnimator oa = ObjectAnimator.ofFloat(this, "progress", 0f);
oa.setDuration(ANIMATE_TIME);
oa.setInterpolator(AnimationUtils.SLOW_FAST_INTERPOLATOR);
oa.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
mInAnimation = true;
}
@Override
public void onAnimationEnd(Animator animation) {
mListContainer.setVisibility(View.GONE);
mInAnimation = false;
}
});
oa.setAutoCancel(true);
oa.start();
} else {
setProgress(0f);
mListContainer.setVisibility(View.GONE);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (mListContainer.getVisibility() == View.VISIBLE && (!mInAnimation || mHeight == 0)) {
mWidth = right - left;
mHeight = bottom - top;
}
}
public float getProgress() {
return mProgress;
}
@Keep
public void setProgress(float progress) {
mProgress = progress;
invalidate();
}
public SearchEditText getEditText() {
return mEditText;
}
@Override
public void draw(@NonNull Canvas canvas) {
if (mInAnimation && mHeight != 0) {
final int state = canvas.save();
int bottom = MathUtils.lerp(mBaseHeight, mHeight, mProgress);
mRect.set(0, 0, mWidth, bottom);
setClipBounds(mRect);
canvas.clipRect(mRect);
super.draw(canvas);
canvas.restoreToCount(state);
} else {
setClipBounds(null);
super.draw(canvas);
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Empty
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Empty
}
@Override
public void afterTextChanged(Editable s) {
updateSuggestions();
}
@Override
public void onClick() {
mHelper.onSearchEditTextClick();
}
@Override
public void onBackPressed() {
mHelper.onSearchEditTextBackPressed();
}
@Override
public Parcelable onSaveInstanceState() {
final Bundle state = new Bundle();
state.putParcelable(STATE_KEY_SUPER, super.onSaveInstanceState());
state.putInt(STATE_KEY_STATE, mState);
return state;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
final Bundle savedState = (Bundle) state;
super.onRestoreInstanceState(savedState.getParcelable(STATE_KEY_SUPER));
setState(savedState.getInt(STATE_KEY_STATE), false);
}
}
public interface Helper {
void onClickreplacedle();
void onClickLeftIcon();
void onClickRightIcon();
void onSearchEditTextClick();
void onApplySearch(String query);
void onSearchEditTextBackPressed();
}
public interface OnStateChangeListener {
void onStateChange(SearchBar searchBar, int newState, int oldState, boolean animation);
}
public interface SuggestionProvider {
List<Suggestion> providerSuggestions(String text);
}
public abstract static clreplaced Suggestion {
public abstract CharSequence getText(TextView textView);
public abstract void onClick();
public boolean onLongClick() {
return false;
}
}
private static clreplaced SuggestionHolder extends RecyclerView.ViewHolder {
TextView text1;
TextView text2;
public SuggestionHolder(@NonNull View itemView) {
super(itemView);
text1 = itemView.findViewById(android.R.id.text1);
text2 = itemView.findViewById(android.R.id.text2);
}
}
private clreplaced SuggestionAdapter extends RecyclerView.Adapter<SuggestionHolder> {
private final LayoutInflater mInflater;
private SuggestionAdapter(LayoutInflater inflater) {
mInflater = inflater;
}
@NonNull
@Override
public SuggestionHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new SuggestionHolder(mInflater.inflate(R.layout.item_simple_list_2, parent, false));
}
@Override
public void onBindViewHolder(@NonNull SuggestionHolder holder, int position) {
Suggestion suggestion = mSuggestionList.get(position);
CharSequence text1 = suggestion.getText(holder.text1);
CharSequence text2 = suggestion.getText(holder.text2);
holder.text1.setText(text1);
if (text2 == null) {
holder.text2.setVisibility(View.GONE);
holder.text2.setText("");
} else {
holder.text2.setVisibility(View.VISIBLE);
holder.text2.setText(text2);
}
holder.itemView.setOnClickListener(v -> {
if (position < mSuggestionList.size()) {
mSuggestionList.get(position).onClick();
}
});
holder.itemView.setOnLongClickListener(v -> {
if (position < mSuggestionList.size()) {
return mSuggestionList.get(position).onLongClick();
} else {
return false;
}
});
}
@Override
public long gereplacedemId(int position) {
return position;
}
@Override
public int gereplacedemCount() {
return mSuggestionList.size();
}
}
public clreplaced TagSuggestion extends SearchBar.Suggestion {
public String mHint;
public String mKeyword;
private TagSuggestion(String hint, String keyword) {
mHint = hint;
mKeyword = keyword;
}
@Override
public CharSequence getText(TextView textView) {
if (textView.getId() == android.R.id.text1) {
return mKeyword;
} else {
return mHint;
}
}
@Override
public void onClick() {
Editable editable = mEditText.getText();
if (editable != null) {
String text = editable.toString();
String temp = wrapTagKeyword(mKeyword) + " ";
if (text.contains(" ")) {
temp = text.substring(0, text.lastIndexOf(" ")) + " " + temp;
}
mEditText.setText(temp);
mEditText.setSelection(editable.length());
}
}
}
public clreplaced KeywordSuggestion extends Suggestion {
private final String mKeyword;
private KeywordSuggestion(String keyword) {
mKeyword = keyword;
}
@Override
public CharSequence getText(TextView textView) {
if (textView.getId() == android.R.id.text1) {
return mKeyword;
} else {
return null;
}
}
@Override
public void onClick() {
mEditText.setText(mKeyword);
mEditText.setSelection(mEditText.length());
}
@Override
public boolean onLongClick() {
new MaterialAlertDialogBuilder(getContext()).setMessage(getContext().getString(R.string.delete_search_history, mKeyword)).setNegativeButton(android.R.string.cancel, null).setPositiveButton(R.string.delete, (dialog, which) -> {
mSearchDatabase.deleteQuery(mKeyword);
updateSuggestions(false);
}).show();
return true;
}
}
private String wrapTagKeyword(String keyword) {
keyword = keyword.trim();
int index1 = keyword.indexOf(':');
if (index1 == -1 || index1 >= keyword.length() - 1) {
// Can't find :, or : is the last char
return keyword;
}
if (keyword.charAt(index1 + 1) == '"') {
// The char after : is ", the word must be quoted
return keyword;
}
int index2 = keyword.indexOf(' ');
if (index2 <= index1) {
// Can't find space, or space is before :
return keyword;
}
return keyword.substring(0, index1 + 1) + "\"" + keyword.substring(index1 + 1) + "$\"";
}
}
See More Examples