Add Yorozuya

This commit is contained in:
seven332 committed 2015-07-13 21:44:32 +08:00
1 parent 24faddf5b0
commit a75c4ecffd
77 files changed
+279 -2991

No files matched your search

@@ -29,8 +29,8 @@ import android.widget.TextView;
import com.hippo.ehviewer.Constants;
import com.hippo.ehviewer.R;
import com.hippo.util.AppHandler;
import com.hippo.util.Messenger;
import com.hippo.yorozuya.SimpleHandler;
import com.hippo.yorozuya.Messenger;
import java.util.Locale;
@@ -85,7 +85,7 @@ public abstract class StatsActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
mStatsTextView = new TextView(this);
mHandler = AppHandler.getInstance();
mHandler = SimpleHandler.getInstance();
mStatsClockTickRunnable = new Runnable() {
@Override
public void run() {
@@ -29,7 +29,7 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import com.hippo.ehviewer.R;
import com.hippo.util.MathUtils;
import com.hippo.yorozuya.MathUtils;
public class AddDeleteDrawable extends Drawable {
@@ -29,7 +29,7 @@ import android.graphics.drawable.Drawable;
import android.os.Build;
import com.hippo.ehviewer.R;
import com.hippo.util.MathUtils;
import com.hippo.yorozuya.MathUtils;
/**
* A drawable that can draw a "Drawer hamburger" menu or an Arrow and animate between them.
@@ -21,7 +21,6 @@ import android.animation.ObjectAnimator;
import android.view.View;
import com.hippo.animation.SimpleAnimatorListener;
import com.hippo.util.ViewUtils;
public class ViewTransition {
@@ -81,7 +80,7 @@ public class ViewTransition {
if (i != oldShownView && i != shownView) {
View v = views[i];
v.setAlpha(0f);
ViewUtils.setVisibility(v, View.GONE);
v.setVisibility(View.GONE);
}
}
startAnimations(views[oldShownView], views[shownView]);
@@ -90,10 +89,10 @@ public class ViewTransition {
View v = views[i];
if (i == shownView) {
v.setAlpha(1f);
ViewUtils.setVisibility(v, View.VISIBLE);
v.setVisibility(View.VISIBLE);
} else {
v.setAlpha(0f);
ViewUtils.setVisibility(v, View.GONE);
v.setVisibility(View.GONE);
}
}
}
@@ -110,14 +109,14 @@ public class ViewTransition {
oa1.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
ViewUtils.setVisibility(hiddenView, View.GONE);
hiddenView.setVisibility(View.GONE);
mAnimator1 = null;
}
});
oa1.start();
mAnimator1 = oa1;
ViewUtils.setVisibility(shownView, View.VISIBLE);
shownView.setVisibility(View.VISIBLE);
ObjectAnimator oa2 = ObjectAnimator.ofFloat(shownView, "alpha", 1f);
oa2.setDuration(ANIMATE_TIME);
oa2.addListener(new SimpleAnimatorListener() {
@@ -16,7 +16,7 @@
package com.hippo.ehviewer;
import com.hippo.util.Messenger;
import com.hippo.yorozuya.Messenger;
public final class Constants {
@@ -25,14 +25,16 @@ import com.hippo.ehviewer.client.EhClient;
import com.hippo.ehviewer.network.EhHttpClient;
import com.hippo.ehviewer.util.Settings;
import com.hippo.scene.SceneApplication;
import com.hippo.util.Log;
import com.hippo.vectorold.content.VectorContext;
import com.hippo.yorozuya.Say;
import java.io.File;
import java.io.IOException;
public class EhApplication extends SceneApplication {
private static final String TAG = EhApplication.class.getSimpleName();
private EhHttpClient mEhHttpClient;
private EhClient mEhClient;
private Conaco mConaco;
@@ -80,7 +82,7 @@ public class EhApplication extends SceneApplication {
super.onTrimMemory(level);
if (level == TRIM_MEMORY_UI_HIDDEN) {
Log.d("Application hiden");
Say.d(TAG, "Application hiden");
}
}
@@ -16,7 +16,7 @@
package com.hippo.ehviewer.client;
import com.hippo.util.AssertUtils;
import com.hippo.yorozuya.AssertUtils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -21,7 +21,7 @@ import android.os.Process;
import com.hippo.ehviewer.network.EhHttpRequest;
import com.hippo.httpclient.HttpClient;
import com.hippo.util.PriorityThreadFactory;
import com.hippo.yorozuya.PriorityThreadFactory;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
@@ -23,7 +23,7 @@ import com.hippo.ehviewer.client.data.NormalPreviewSet;
import com.hippo.ehviewer.client.data.PreviewSet;
import com.hippo.ehviewer.client.data.TagGroup;
import com.hippo.ehviewer.util.EhUtils;
import com.hippo.util.Utils;
import com.hippo.yorozuya.NumberUtils;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
@@ -176,7 +176,7 @@ public class GalleryDetailParser {
if (index == -1 || index >= ratingStr.length()) {
galleryDetail.rating = 0f;
} else {
galleryDetail.rating = Utils.parseFloatSafely(ratingStr.substring(index + 1), 0f);
galleryDetail.rating = NumberUtils.parseFloatSafely(ratingStr.substring(index + 1), 0f);
}
}
@@ -21,9 +21,9 @@ import android.support.annotation.NonNull;
import com.hippo.ehviewer.client.data.GalleryInfo;
import com.hippo.ehviewer.client.data.LofiGalleryInfo;
import com.hippo.ehviewer.util.EhUtils;
import com.hippo.util.AssertException;
import com.hippo.util.AssertUtils;
import com.hippo.util.Utils;
import com.hippo.yorozuya.AssertException;
import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.NumberUtils;
import java.util.ArrayList;
import java.util.List;
@@ -123,7 +123,7 @@ public class GalleryListParser {
continue;
}
gi.rating = Utils.parseFloatSafely(getRate(m.group(11)), Float.NaN);
gi.rating = NumberUtils.parseFloatSafely(getRate(m.group(11)), Float.NaN);
gi.uploader = ParserUtils.trim(m.group(12));
gi.generateSLang();
@@ -16,7 +16,7 @@
package com.hippo.ehviewer.client;
import com.hippo.util.Utils;
import com.hippo.yorozuya.StringUtils;
public class ParserUtils {
@@ -25,7 +25,7 @@ public class ParserUtils {
if (str == null) {
str = "";
}
return Utils.unescapeXml(str).trim();
return StringUtils.unescapeXml(str).trim();
}
public static int parseInt(String str) {
@@ -18,7 +18,7 @@ package com.hippo.ehviewer.client;
import com.hippo.ehviewer.client.data.GalleryInfo;
import com.hippo.ehviewer.util.EhUtils;
import com.hippo.util.Utils;
import com.hippo.yorozuya.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
@@ -55,7 +55,7 @@ public class PopularParser {
GalleryInfo gi = new GalleryInfo();
gi.gid = j.getInt("gid");
gi.token = j.getString("token");
gi.title = Utils.unescapeXml(j.getString("title"));
gi.title = StringUtils.unescapeXml(j.getString("title"));
gi.posted = EhUtils.formatPostDate(Long.parseLong(j.getString("posted")) * 1000);
gi.thumb = j.getString("thumb");
gi.category = EhUtils.getCategory(j.getString("category"));
@@ -33,8 +33,8 @@ import com.hippo.conaco.Conaco;
import com.hippo.conaco.Unikery;
import com.hippo.ehviewer.EhImageKeyFactory;
import com.hippo.ehviewer.R;
import com.hippo.util.Log;
import com.hippo.widget.SimpleGridLayout;
import com.hippo.yorozuya.Say;
import java.util.ArrayList;
import java.util.HashSet;
@@ -43,6 +43,8 @@ import java.util.Set;
public class NormalPreviewSet extends PreviewSet {
private static final String TAG = NormalPreviewSet.class.getSimpleName();
private List<Row> mRowArray = new ArrayList<>();
private Set<LoadImageTask> mLoadImageTasks = new HashSet<>();
@@ -258,7 +260,7 @@ public class NormalPreviewSet extends PreviewSet {
try {
imageIndex = Integer.parseInt(imageUrl.substring(index1 + 1, index2));
} catch (Exception e) {
Log.w("Can't get normal preview index", e);
Say.w(TAG, "Can't get normal preview index", e);
imageIndex = -1;
}
}
@@ -25,8 +25,8 @@ import com.hippo.ehviewer.client.EhConfig;
import com.hippo.ehviewer.util.Settings;
import com.hippo.httpclient.Cookie;
import com.hippo.httpclient.HttpClient;
import com.hippo.util.MathUtils;
import com.hippo.util.Utils;
import com.hippo.yorozuya.MathUtils;
import com.hippo.yorozuya.Utilities;
import java.net.URL;
@@ -88,40 +88,28 @@ public class EhHttpClient extends HttpClient {
@Override
protected void fillCookie(URL url, Cookie cookie) {
boolean isSignIn = Settings.getSignIn();
String host = url.getHost();
cookie.putRaw(mCookieManager.getCookie(url.toString()));
if (Utils.contain(EHENTAI_DOMAIN, getDomain(url)))
if (!isSignIn && HOST_EX.equals(host)) {
cookie.put("yay", "louder");
} else {
cookie.putRaw(mCookieManager.getCookie(url.toString()));
if (Utils.contain(EHENTAI_DOMAIN, getDomain(url))) {
if (Settings.getSignIn()) {
// Put login info
String ipdMemberId = Settings.getIpdNumberId();
String ipdPassHash = Settings.getIpdPassHash();
String igneous = Settings.getIgneous();
if (ipdMemberId != null) {
cookie.put(KEY_IPD_MEMBER_ID, ipdMemberId);
}
if (ipdPassHash != null) {
cookie.put(KEY_IPD_PASS_HASH, ipdPassHash);
}
if (igneous != null) {
cookie.put(KEY_IGNEOUS, igneous);
}
} else if (HOST_EX.equals(url.getHost())) {
cookie.put("yay", "louder");
if (Utilities.contain(EHENTAI_DOMAIN, getDomain(url))) {
if (Settings.getSignIn()) {
// Put login info
String ipdMemberId = Settings.getIpdNumberId();
String ipdPassHash = Settings.getIpdPassHash();
String igneous = Settings.getIgneous();
if (ipdMemberId != null) {
cookie.put(KEY_IPD_MEMBER_ID, ipdMemberId);
}
mEhConfig.fillCookie(cookie);
if (ipdPassHash != null) {
cookie.put(KEY_IPD_PASS_HASH, ipdPassHash);
}
if (igneous != null) {
cookie.put(KEY_IGNEOUS, igneous);
}
} else if (HOST_EX.equals(url.getHost())) {
cookie.put("yay", "louder");
}
mEhConfig.fillCookie(cookie);
}
}
@@ -130,26 +118,28 @@ public class EhHttpClient extends HttpClient {
Cookie cookie = new Cookie();
cookie.putRaw(cookieStr);
String ipdMemberId = cookie.get(KEY_IPD_MEMBER_ID);
String ipdPassHash = cookie.get(KEY_IPD_PASS_HASH);
String igneous = cookie.get(KEY_IGNEOUS);
if (ipdMemberId != null) {
Settings.putIpdMemberId(ipdMemberId);
}
if (ipdPassHash != null) {
Settings.putIpdPassHash(ipdPassHash);
}
if (igneous != null) {
Settings.putIgneous(igneous);
}
if (Utilities.contain(EHENTAI_DOMAIN, getDomain(url))) {
String ipdMemberId = cookie.get(KEY_IPD_MEMBER_ID);
String ipdPassHash = cookie.get(KEY_IPD_PASS_HASH);
String igneous = cookie.get(KEY_IGNEOUS);
if (ipdMemberId != null) {
Settings.putIpdMemberId(ipdMemberId);
}
if (ipdPassHash != null) {
Settings.putIpdPassHash(ipdPassHash);
}
if (igneous != null) {
Settings.putIgneous(igneous);
}
cookie.remove(KEY_IPD_MEMBER_ID);
cookie.remove(KEY_IPD_MEMBER_ID);
cookie.remove(KEY_IGNEOUS);
cookie.remove(KEY_YAY);
cookie.remove(EhConfig.KEY_UCONFIG);
cookie.remove(EhConfig.KEY_LOFI_RESOLUTION);
cookie.remove(EhConfig.KEY_CONTENT_WARNING);
cookie.remove(KEY_IPD_MEMBER_ID);
cookie.remove(KEY_IPD_MEMBER_ID);
cookie.remove(KEY_IGNEOUS);
cookie.remove(KEY_YAY);
cookie.remove(EhConfig.KEY_UCONFIG);
cookie.remove(EhConfig.KEY_LOFI_RESOLUTION);
cookie.remove(EhConfig.KEY_CONTENT_WARNING);
}
mCookieManager.setCookie(url.toString(), cookie.toString());
}
@@ -39,7 +39,7 @@ import com.hippo.scene.SceneManager;
import com.hippo.scene.SimpleCurtain;
import com.hippo.scene.StageActivity;
import com.hippo.scene.StageLayout;
import com.hippo.util.Messenger;
import com.hippo.yorozuya.Messenger;
import com.hippo.vectorold.content.VectorContext;
import com.hippo.widget.DrawerLayout;
import com.hippo.widget.DrawerListView;
@@ -19,9 +19,9 @@ import com.hippo.rippleold.RippleSalon;
import com.hippo.scene.Announcer;
import com.hippo.scene.AppbarScene;
import com.hippo.util.URLImageGetter;
import com.hippo.util.UiUtils;
import com.hippo.widget.recyclerview.EasyRecyclerView;
import com.hippo.widget.recyclerview.LinearDividerItemDecoration;
import com.hippo.yorozuya.LayoutUtils;
import java.util.List;
@@ -66,7 +66,7 @@ public class CommentScene extends AppbarScene implements EasyRecyclerView.OnItem
mRecyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(
LinearDividerItemDecoration.VERTICAL, resources.getColor(R.color.divider_light),
UiUtils.dp2pix(getStageActivity(), 1));
LayoutUtils.dp2pix(getStageActivity(), 1));
decoration.setShowLastDivider(true);
decoration.setPadding(resources.getDimensionPixelOffset(R.dimen.keyline_margin));
mRecyclerView.addItemDecoration(decoration);
@@ -57,12 +57,12 @@ import com.hippo.scene.Announcer;
import com.hippo.scene.RippleCurtain;
import com.hippo.scene.Scene;
import com.hippo.scene.SimpleDialog;
import com.hippo.util.Log;
import com.hippo.util.URLImageGetter;
import com.hippo.util.UiUtils;
import com.hippo.util.ViewUtils;
import com.hippo.widget.AccurateClick;
import com.hippo.widget.AutoWrapLayout;
import com.hippo.yorozuya.LayoutUtils;
import com.hippo.yorozuya.Say;
import com.hippo.yorozuya.ViewUtils;
import java.util.List;
@@ -72,6 +72,8 @@ import static com.hippo.ehviewer.R.id.no_tags;
public class GalleryDetailScene extends Scene implements View.OnClickListener,
AccurateClick.OnAccurateClickListener {
private static final String TAG = GalleryDetailScene.class.getSimpleName();
public static final String ACTION_GALLERY_INFO = "action_gallery_info";
public static final String ACTION_GID_TOKEN = "action_gid_token";
public static final String ACTION_URL = "action_url";
@@ -134,7 +136,7 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener,
private void handleAnnouncer(Announcer announcer) {
if (announcer == null) {
Log.e("No announcer in GalleryDetailScene, finish itself");
Say.e(TAG, "No announcer in GalleryDetailScene, finish itself");
finish();
return;
}
@@ -199,7 +201,7 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener,
mPreviewLayout.setPreviewHelper(new SimplePreviewHelper());
} else {
Log.e("Can't get GalleryDetail");
Say.e(TAG, "Can't get GalleryDetail");
finish();
}
@@ -208,7 +210,7 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener,
} else if (ACTION_URL.equals(action)) {
} else {
Log.e("Unkonwn action " + action);
Say.e(TAG, "Unkonwn action " + action);
finish();
}
}
@@ -357,8 +359,8 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener,
Context context = getStageActivity();
LayoutInflater inflater = getStageActivity().getLayoutInflater();
int x = UiUtils.dp2pix(context, 2);
int y = UiUtils.dp2pix(context, 4);
int x = LayoutUtils.dp2pix(context, 2);
int y = LayoutUtils.dp2pix(context, 4);
for (TagGroup tagGroup : tags) {
LinearLayout tagGroupLayout = new LinearLayout(context);
@@ -67,13 +67,13 @@ import com.hippo.scene.Scene;
import com.hippo.scene.SimpleDialog;
import com.hippo.scene.TransitionCurtain;
import com.hippo.util.AnimationUtils;
import com.hippo.util.AppHandler;
import com.hippo.util.AssertUtils;
import com.hippo.util.MathUtils;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.SimpleHandler;
import com.hippo.yorozuya.AssertUtils;
import com.hippo.widget.FabLayout;
import com.hippo.widget.FloatingActionButton;
import com.hippo.widget.recyclerview.EasyRecyclerView;
import com.hippo.yorozuya.MathUtils;
import com.hippo.yorozuya.ViewUtils;
// TODO remeber the data in ContentHelper after screen dirction change
// TODO Must refresh when change source
@@ -796,8 +796,7 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper,
isVaildView(recyclerView)) {
int oldBottom = mSearchBar.getBottom();
int offsetYStep = MathUtils.clamp(-dy,
-mSearchBar.getBottom(), mSearchBarOriginalTop - mSearchBar.getTop());
int offsetYStep = MathUtils.clamp(-dy, -mSearchBar.getBottom(), mSearchBarOriginalTop - mSearchBar.getTop());
mSearchBar.offsetTopAndBottom(offsetYStep);
((OffsetLayout.LayoutParams) mSearchBar.getLayoutParams()).offsetY += offsetYStep;
int newBottom = mSearchBar.getBottom();
@@ -877,7 +876,7 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper,
@Override
protected void onScrollToPosition() {
AppHandler.getInstance().post(mSearchBarPositionTask);
SimpleHandler.getInstance().post(mSearchBarPositionTask);
}
@Override
@@ -34,9 +34,9 @@ import com.hippo.ehviewer.util.EhUtils;
import com.hippo.rippleold.RippleSalon;
import com.hippo.scene.Announcer;
import com.hippo.scene.AppbarScene;
import com.hippo.util.UiUtils;
import com.hippo.widget.recyclerview.EasyRecyclerView;
import com.hippo.widget.recyclerview.LinearDividerItemDecoration;
import com.hippo.yorozuya.LayoutUtils;
import java.util.ArrayList;
import java.util.List;
@@ -70,7 +70,7 @@ public class InfoScene extends AppbarScene implements EasyRecyclerView.OnItemLon
recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false));
LinearDividerItemDecoration decoration = new LinearDividerItemDecoration(
LinearDividerItemDecoration.VERTICAL, mResources.getColor(R.color.divider_light),
UiUtils.dp2pix(getStageActivity(), 1));
LayoutUtils.dp2pix(getStageActivity(), 1));
decoration.setPadding(mResources.getDimensionPixelOffset(R.dimen.keyline_margin));
recyclerView.addItemDecoration(decoration);
recyclerView.setSelector(RippleSalon.generateRippleDrawable(false));
@@ -30,7 +30,7 @@ import com.hippo.ehviewer.client.EhRequest;
import com.hippo.ehviewer.util.Settings;
import com.hippo.rippleold.RippleSalon;
import com.hippo.scene.Scene;
import com.hippo.util.Messenger;
import com.hippo.yorozuya.Messenger;
public final class SignInScene extends Scene implements View.OnClickListener,
TextView.OnEditorActionListener {
@@ -26,7 +26,7 @@ import com.hippo.scene.preference.PreferenceCategory;
import com.hippo.scene.preference.PreferenceScene;
import com.hippo.scene.preference.PreferenceSet;
import com.hippo.scene.preference.SwitchPreference;
import com.hippo.util.Messenger;
import com.hippo.yorozuya.Messenger;
public class AdvanceSettingsScene extends PreferenceScene implements Preference.OnValueChangeListener {
@@ -29,7 +29,7 @@ import com.hippo.scene.preference.Preference;
import com.hippo.scene.preference.PreferenceCategory;
import com.hippo.scene.preference.PreferenceScene;
import com.hippo.scene.preference.PreferenceSet;
import com.hippo.util.Messenger;
import com.hippo.yorozuya.Messenger;
public final class EHSettingsScene extends PreferenceScene implements Preference.OnClickListener,
Preference.OnValueChangeListener {
@@ -27,7 +27,7 @@ import android.widget.Spinner;
import android.widget.TableLayout;
import com.hippo.ehviewer.R;
import com.hippo.util.Utils;
import com.hippo.yorozuya.NumberUtils;
public class AdvanceSearchTable extends TableLayout {
@@ -113,14 +113,14 @@ public class AdvanceSearchTable extends TableLayout {
}
public void setAdvanceSearch(int advanceSearch) {
mSname.setChecked(Utils.int2boolean(advanceSearch & SNAME));
mStags.setChecked(Utils.int2boolean(advanceSearch & STAGS));
mSdesc.setChecked(Utils.int2boolean(advanceSearch & SDESC));
mStorr.setChecked(Utils.int2boolean(advanceSearch & STORR));
mSto.setChecked(Utils.int2boolean(advanceSearch & STO));
mSdt1.setChecked(Utils.int2boolean(advanceSearch & SDT1));
mSdt2.setChecked(Utils.int2boolean(advanceSearch & SDT2));
mSh.setChecked(Utils.int2boolean(advanceSearch & SH));
mSname.setChecked(NumberUtils.int2boolean(advanceSearch & SNAME));
mStags.setChecked(NumberUtils.int2boolean(advanceSearch & STAGS));
mSdesc.setChecked(NumberUtils.int2boolean(advanceSearch & SDESC));
mStorr.setChecked(NumberUtils.int2boolean(advanceSearch & STORR));
mSto.setChecked(NumberUtils.int2boolean(advanceSearch & STO));
mSdt1.setChecked(NumberUtils.int2boolean(advanceSearch & SDT1));
mSdt2.setChecked(NumberUtils.int2boolean(advanceSearch & SDT2));
mSh.setChecked(NumberUtils.int2boolean(advanceSearch & SH));
}
public void setMinRating(int minRating) {
@@ -26,8 +26,8 @@ import android.widget.TableLayout;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.client.EhConfig;
import com.hippo.util.Utils;
import com.hippo.widget.CheckTextView;
import com.hippo.yorozuya.NumberUtils;
public class CategoryTable extends TableLayout {
@@ -86,16 +86,16 @@ public class CategoryTable extends TableLayout {
* @param category target category
*/
public void setCategory(int category) {
mDoujinshi.setChecked(!Utils.int2boolean(category & EhConfig.DOUJINSHI), false);
mManga.setChecked(!Utils.int2boolean(category & EhConfig.MANGA), false);
mArtistCG.setChecked(!Utils.int2boolean(category & EhConfig.ARTIST_CG), false);
mGameCG.setChecked(!Utils.int2boolean(category & EhConfig.GAME_CG), false);
mWestern.setChecked(!Utils.int2boolean(category & EhConfig.WESTERN), false);
mNonH.setChecked(!Utils.int2boolean(category & EhConfig.NON_H), false);
mImageSets.setChecked(!Utils.int2boolean(category & EhConfig.IMAGE_SET), false);
mCosplay.setChecked(!Utils.int2boolean(category & EhConfig.COSPLAY), false);
mAsianPorn.setChecked(!Utils.int2boolean(category & EhConfig.ASIAN_PORN), false);
mMisc.setChecked(!Utils.int2boolean(category & EhConfig.MISC), false);
mDoujinshi.setChecked(!NumberUtils.int2boolean(category & EhConfig.DOUJINSHI), false);
mManga.setChecked(!NumberUtils.int2boolean(category & EhConfig.MANGA), false);
mArtistCG.setChecked(!NumberUtils.int2boolean(category & EhConfig.ARTIST_CG), false);
mGameCG.setChecked(!NumberUtils.int2boolean(category & EhConfig.GAME_CG), false);
mWestern.setChecked(!NumberUtils.int2boolean(category & EhConfig.WESTERN), false);
mNonH.setChecked(!NumberUtils.int2boolean(category & EhConfig.NON_H), false);
mImageSets.setChecked(!NumberUtils.int2boolean(category & EhConfig.IMAGE_SET), false);
mCosplay.setChecked(!NumberUtils.int2boolean(category & EhConfig.COSPLAY), false);
mAsianPorn.setChecked(!NumberUtils.int2boolean(category & EhConfig.ASIAN_PORN), false);
mMisc.setChecked(!NumberUtils.int2boolean(category & EhConfig.MISC), false);
}
/**
@@ -31,20 +31,22 @@ import android.widget.Toast;
import com.hippo.effect.ViewTransition;
import com.hippo.ehviewer.R;
import com.hippo.util.AssertUtils;
import com.hippo.util.ExceptionUtils;
import com.hippo.util.IntIdGenerator;
import com.hippo.util.LayoutManagerUtils;
import com.hippo.util.Log;
import com.hippo.util.UiUtils;
import com.hippo.widget.recyclerview.EasyRecyclerView;
import com.hippo.widget.refreshlayout.RefreshLayout;
import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.IdGenerator;
import com.hippo.yorozuya.LayoutUtils;
import com.hippo.yorozuya.Say;
import java.util.ArrayList;
import java.util.List;
public class ContentLayout extends FrameLayout {
private static final String TAG = ContentLayout.class.getSimpleName();
private ProgressBar mProgressBar;
private ViewGroup mTipView;
private RefreshLayout mRefreshLayout;
@@ -113,7 +115,7 @@ public class ContentLayout extends FrameLayout {
// RecyclerView
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerViewOriginTop + fitPaddingTop, mRecyclerView.getPaddingRight(), mRecyclerView.getPaddingBottom());
// RefreshLayout
mRefreshLayout.setProgressViewOffset(false, fitPaddingTop, fitPaddingTop + UiUtils.dp2pix(getContext(), 32)); // TODO
mRefreshLayout.setProgressViewOffset(false, fitPaddingTop, fitPaddingTop + LayoutUtils.dp2pix(getContext(), 32)); // TODO
}
public void setFitPaddingBottom(int fitPaddingBottom) {
@@ -178,7 +180,7 @@ public class ContentLayout extends FrameLayout {
*/
private List<E> mData;
private IntIdGenerator mIdGenerator;
private IdGenerator mIdGenerator;
/**
* First shown page index
@@ -254,7 +256,7 @@ public class ContentLayout extends FrameLayout {
public ContentHelper(Context context) {
mContext = context;
mData = new ArrayList<>();
mIdGenerator = IntIdGenerator.create();
mIdGenerator = new IdGenerator();
}
@SuppressWarnings("unchecked")
@@ -442,7 +444,7 @@ public class ContentLayout extends FrameLayout {
if (mCurrentTaskId == taskId) {
mRefreshLayout.setHeaderRefreshing(false);
mRefreshLayout.setFooterRefreshing(false);
Log.d("Get page data failed " + e.getClass().getName() + " " + e.getMessage());
Say.d(TAG, "Get page data failed " + e.getClass().getName() + " " + e.getMessage());
String readableError = ExceptionUtils.getReadableString(mContext, e);
String reason = ExceptionUtils.getReasonString(mContext, e);
if (reason != null) {
@@ -32,7 +32,7 @@ import com.hippo.ehviewer.Constants;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.util.Settings;
import com.hippo.rippleold.RippleSalon;
import com.hippo.util.Messenger;
import com.hippo.yorozuya.Messenger;
import com.hippo.widget.DrawerListView;
import com.hippo.widget.FitPaddingImpl;
@@ -33,9 +33,9 @@ import com.hippo.ehviewer.R;
import com.hippo.ehviewer.client.data.LargePreviewSet;
import com.hippo.ehviewer.client.data.PreviewSet;
import com.hippo.rippleold.RippleSalon;
import com.hippo.util.ViewUtils;
import com.hippo.widget.AccurateClick;
import com.hippo.widget.SimpleGridLayout;
import com.hippo.yorozuya.ViewUtils;
public final class PreviewLayout extends LinearLayout implements View.OnClickListener,
AccurateClick.OnAccurateClickListener {
@@ -10,7 +10,7 @@ import android.view.MotionEvent;
import android.view.View;
import com.hippo.ehviewer.R;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.ViewUtils;
public class RatingView extends View {
@@ -53,10 +53,10 @@ import com.hippo.ehviewer.Constants;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.client.EhUrl;
import com.hippo.ehviewer.util.Settings;
import com.hippo.util.MathUtils;
import com.hippo.util.Messenger;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.Messenger;
import com.hippo.widget.SimpleImageView;
import com.hippo.yorozuya.MathUtils;
import com.hippo.yorozuya.ViewUtils;
import java.util.ArrayList;
import java.util.Collections;
@@ -144,8 +144,7 @@ public class SearchBar extends CardView implements View.OnClickListener,
mEditText.addTextChangedListener(this);
// Get base height
ViewUtils.measureView(this, ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
ViewUtils.measureView(this, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
mBaseHeight = getMeasuredHeight();
mSuggestionList = new ArrayList<>();
@@ -299,7 +298,7 @@ public class SearchBar extends CardView implements View.OnClickListener,
oa.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
ViewUtils.setVisibility(mList, View.VISIBLE);
mList.setVisibility(View.VISIBLE);
mInAnimation = true;
}
@@ -313,7 +312,7 @@ public class SearchBar extends CardView implements View.OnClickListener,
}
oa.start();
} else {
ViewUtils.setVisibility(mList, View.VISIBLE);
mList.setVisibility(View.VISIBLE);
setProgress(1f);
}
}
@@ -338,7 +337,7 @@ public class SearchBar extends CardView implements View.OnClickListener,
@Override
public void onAnimationEnd(Animator animation) {
ViewUtils.setVisibility(mList, View.GONE);
mList.setVisibility(View.GONE);
mInAnimation = false;
}
});
@@ -348,7 +347,7 @@ public class SearchBar extends CardView implements View.OnClickListener,
oa.start();
} else {
setProgress(0f);
ViewUtils.setVisibility(mList, View.GONE);
mList.setVisibility(View.GONE);
}
}
@@ -23,7 +23,7 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import com.hippo.util.Log;
import com.hippo.yorozuya.Say;
import java.util.LinkedList;
import java.util.List;
@@ -126,7 +126,7 @@ public class SearchDatabase {
}
mDatabase.delete(TABLE_SUGGESTIONS, selection, null);
} catch (RuntimeException e) {
Log.e(TAG, "truncateHistory", e);
Say.e(TAG, "truncateHistory", e);
}
}
@@ -40,10 +40,10 @@ import com.hippo.ehviewer.client.data.ListUrlBuilder;
import com.hippo.rippleold.RippleSalon;
import com.hippo.scene.Scene;
import com.hippo.scene.SimpleDialog;
import com.hippo.util.UiUtils;
import com.hippo.util.ViewUtils;
import com.hippo.widget.recyclerview.EasyRecyclerView;
import com.hippo.widget.recyclerview.MonoRecyclerView;
import com.hippo.yorozuya.LayoutUtils;
import com.hippo.yorozuya.ViewUtils;
// TODO requst returnSearchBarPosition when content of recycler changed
public class SearchLayout extends MonoRecyclerView implements CompoundButton.OnCheckedChangeListener,
@@ -129,7 +129,7 @@ public class SearchLayout extends MonoRecyclerView implements CompoundButton.OnC
// Search Container
mSearchPaddingTopOrigin = getPaddingTop();
// Original padding bottom and the padding bottom to make it above fab
mSearchPaddingBottomOrigin = getPaddingBottom() + UiUtils.dp2pix(context, 72); // TODO
mSearchPaddingBottomOrigin = getPaddingBottom() + LayoutUtils.dp2pix(context, 72); // TODO
setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), mSearchPaddingBottomOrigin);
// Create normal view
@@ -33,7 +33,6 @@ import android.widget.TextView;
import com.hippo.ehviewer.R;
import com.hippo.rippleold.RippleSalon;
import com.hippo.util.ViewUtils;
public class SelectSearchImageLayout extends LinearLayout implements View.OnClickListener{
@@ -119,8 +118,8 @@ public class SelectSearchImageLayout extends LinearLayout implements View.OnClic
mTextPath.setText(selectPath);
setImagePreview(selectPath);
ViewUtils.setVisibility(mTextPath, View.VISIBLE);
ViewUtils.setVisibility(mImagePreview, View.VISIBLE);
mTextPath.setVisibility(View.VISIBLE);
mImagePreview.setVisibility(View.VISIBLE);
super.onDetachedFromWindow();
super.onAttachedToWindow();
@@ -26,7 +26,6 @@ import android.widget.TextView;
import com.hippo.ehviewer.R;
import com.hippo.rippleold.RippleSalon;
import com.hippo.util.ViewUtils;
import com.hippo.widget.SimpleImageView;
public class AppbarScene extends Scene {
@@ -73,12 +72,12 @@ public class AppbarScene extends Scene {
public void setIcon(@DrawableRes int resId) {
mIcon.setDrawable(resId);
ViewUtils.setVisibility(mIcon, resId == -1 ? View.GONE : View.VISIBLE);
mIcon.setVisibility(resId == -1 ? View.GONE : View.VISIBLE);
}
public void setIcon(Drawable icon) {
mIcon.setDrawable(icon);
ViewUtils.setVisibility(mIcon, icon == null ? View.GONE : View.VISIBLE);
mIcon.setVisibility(icon == null ? View.GONE : View.VISIBLE);
}
public void setTitle(@StringRes int resId) {
@@ -10,8 +10,8 @@ import android.view.ViewTreeObserver;
import com.hippo.animation.DurationInterpolator;
import com.hippo.animation.SimpleAnimatorListener;
import com.hippo.util.Log;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.Say;
import com.hippo.yorozuya.ViewUtils;
import java.util.HashSet;
import java.util.Set;
@@ -45,7 +45,7 @@ public class RippleCurtain extends Curtain {
final SceneView enterView = enter.getSceneView();
enterView.setStartPoint(mStartX, mStartY);
ViewUtils.setVisibility(enterView, View.INVISIBLE);
enterView.setVisibility(View.INVISIBLE);
enterView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
@@ -67,7 +67,7 @@ public class RippleCurtain extends Curtain {
});
animatorCollection.add(alphaAnim);
} else {
Log.w(TAG, "Can't get enter scene content view");
Say.w(TAG, "Can't get enter scene content view");
}
PropertyValuesHolder circlePercentPvh = PropertyValuesHolder.ofFloat("circlePercent", 0f, 1f);
@@ -80,7 +80,7 @@ public class RippleCurtain extends Curtain {
mAnimatorSet.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
ViewUtils.setVisibility(enterView, View.VISIBLE);
enterView.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
+2 -2
View File
@@ -30,8 +30,8 @@ import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;
import android.widget.FrameLayout;
import com.hippo.util.AssertUtils;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.ViewUtils;
/**
* {@link com.hippo.scene.Scene} is a {@code Activity} of {@link android.app.Activity}.
@@ -20,8 +20,8 @@ import android.app.Application;
import android.content.Context;
import android.util.SparseArray;
import com.hippo.util.IntIdGenerator;
import com.hippo.util.Log;
import com.hippo.yorozuya.IdGenerator;
import com.hippo.yorozuya.Say;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.RefWatcher;
@@ -29,7 +29,7 @@ public class SceneApplication extends Application {
private static final String TAG = SceneApplication.class.getSimpleName();
private SparseArray<SceneManager> mSceneManagers;
private IntIdGenerator mIdGenerator;
private IdGenerator mIdGenerator;
private RefWatcher mRefWatcher;
@@ -38,7 +38,7 @@ public class SceneApplication extends Application {
super.onCreate();
mSceneManagers = new SparseArray<>();
mIdGenerator = IntIdGenerator.create();
mIdGenerator = new IdGenerator();
mRefWatcher = LeakCanary.install(this);
}
@@ -53,7 +53,7 @@ public class SceneApplication extends Application {
private SceneManager getSceneManager(int id) {
SceneManager sceneManager = mSceneManagers.get(id);
if (sceneManager == null) {
Log.e(TAG, "Can't get SceneManager by id " + id);
Say.e(TAG, "Can't get SceneManager by id " + id);
sceneManager = new SceneManager(id);
}
return sceneManager;
@@ -24,7 +24,7 @@ import android.view.ViewGroup;
import com.hippo.hotspot.HotspotTouchHelper;
import com.hippo.hotspot.Hotspotable;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.ViewUtils;
public class SceneDialogView extends SceneView implements View.OnClickListener, Hotspotable {
@@ -76,8 +76,7 @@ public class SceneDialogView extends SceneView implements View.OnClickListener,
@Override
public void onClick(View v) {
if (v == this && !ViewUtils.isViewUnder(((ViewGroup) getChildAt(0)).getChildAt(0), (int) mHostpotX,
(int) mHostpotY) && mOnClickOutOfDialogListener != null) {
if (v == this && !ViewUtils.isViewUnder(((ViewGroup) getChildAt(0)).getChildAt(0), (int) mHostpotX, (int) mHostpotY) && mOnClickOutOfDialogListener != null) {
mOnClickOutOfDialogListener.onClickOutOfDialog((int) mHostpotX, (int) mHostpotY);
}
}
@@ -21,9 +21,9 @@ import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.hippo.util.AssertUtils;
import com.hippo.util.IntIdGenerator;
import com.hippo.util.Log;
import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.IdGenerator;
import com.hippo.yorozuya.Say;
import java.util.ArrayList;
import java.util.HashSet;
@@ -44,7 +44,7 @@ public class SceneManager {
private Set<Scene> mLegacySceneSet = new HashSet<>();
private Set<Scene> mPrepareToDieSceneSet = new HashSet<>();
private IntIdGenerator mIdGenerator = IntIdGenerator.create();
private IdGenerator mIdGenerator = new IdGenerator();
private List<SceneStateListener> mSceneStateListenerList = new ArrayList<>();
@@ -166,7 +166,7 @@ public class SceneManager {
checkLoop();
if (!isStageAlive()) {
Log.w(TAG, "Stage is not alive, but attemp to show dialog " + dialog.toString());
Say.w(TAG, "Stage is not alive, but attemp to show dialog " + dialog.toString());
return;
}
@@ -282,7 +282,7 @@ public class SceneManager {
}
}
} else {
Log.e(TAG, "The scene is not in stage, " + scene);
Say.e(TAG, "The scene is not in stage, " + scene);
}
}
@@ -327,7 +327,7 @@ public class SceneManager {
scene.onBackPressedInternal();
return true;
} else {
Log.w(TAG, "There is no scene in the stage");
Say.w(TAG, "There is no scene in the stage");
return false;
}
}
@@ -25,7 +25,7 @@ import android.view.ViewTreeObserver;
import com.hippo.animation.SimpleAnimatorListener;
import com.hippo.util.AnimationUtils;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.ViewUtils;
public class SimpleCurtain extends Curtain {
@@ -47,7 +47,7 @@ public class SimpleCurtain extends Curtain {
@Override
public void open(@NonNull final Scene enter, @NonNull final Scene exit) {
final View enterSceneView = enter.getSceneView();
ViewUtils.setVisibility(enterSceneView, View.INVISIBLE);
enterSceneView.setVisibility(View.INVISIBLE);
enterSceneView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
@@ -85,7 +85,7 @@ public class SimpleCurtain extends Curtain {
animator.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
ViewUtils.setVisibility(enterSceneView, View.VISIBLE);
enterSceneView.setVisibility(View.VISIBLE);
}
@Override
@@ -34,7 +34,6 @@ import android.widget.TextView;
import com.hippo.cardsalon.CardView;
import com.hippo.ehviewer.R;
import com.hippo.rippleold.RippleSalon;
import com.hippo.util.ViewUtils;
public class SimpleDialog extends SceneDialog implements View.OnClickListener,
SceneDialogView.OnClickOutOfDialogListener, AdapterView.OnItemClickListener {
@@ -116,19 +115,19 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener,
if (mBuilder.mTitle == null && mBuilder.mMessage == null
&& mBuilder.mItemLayoutResId == 0 && mBuilder.mCustomViewResId == 0) {
ViewUtils.setVisibility(mBody, View.GONE);
mBody.setVisibility(View.GONE);
} else {
if (mBuilder.mTitle != null) {
mTitle.setText(mBuilder.mTitle);
} else {
ViewUtils.setVisibility(mTitle, View.GONE);
ViewUtils.setVisibility(mSpaceTitleContent, View.GONE);
mTitle.setVisibility(View.GONE);
mSpaceTitleContent.setVisibility(View.GONE);
}
if (mBuilder.mMessage != null) {
mMessage.setText(mBuilder.mMessage);
ViewUtils.setVisibility(mListView, View.GONE);
ViewUtils.setVisibility(mCustom, View.GONE);
mListView.setVisibility(View.GONE);
mCustom.setVisibility(View.GONE);
} else if (mBuilder.mItemLayoutResId != 0) {
listView.setAdapter(new ArrayAdapter<>(getStageActivity(),
mBuilder.mItemLayoutResId, android.R.id.text1, mBuilder.mItems));
@@ -140,42 +139,42 @@ public class SimpleDialog extends SceneDialog implements View.OnClickListener,
listView.setSelection(mBuilder.mCheckedItem);
}
}
ViewUtils.setVisibility(mContent, View.GONE);
ViewUtils.setVisibility(mCustom, View.GONE);
mContent.setVisibility(View.GONE);
mCustom.setVisibility(View.GONE);
} else if (mBuilder.mCustomViewResId != 0) {
getStageActivity().getLayoutInflater().inflate(mBuilder.mCustomViewResId, mCustom);
if (mBuilder.mOnCreateCustomViewListener != null) {
mBuilder.mOnCreateCustomViewListener.onCreateCustomView(this,
mCustom.getChildAt(0));
}
ViewUtils.setVisibility(mContent, View.GONE);
ViewUtils.setVisibility(mListView, View.GONE);
mContent.setVisibility(View.GONE);
mListView.setVisibility(View.GONE);
} else {
ViewUtils.setVisibility(mContent, View.GONE);
ViewUtils.setVisibility(mListView, View.GONE);
ViewUtils.setVisibility(mCustom, View.GONE);
ViewUtils.setVisibility(mSpaceTitleContent, View.GONE);
mContent.setVisibility(View.GONE);
mListView.setVisibility(View.GONE);
mCustom.setVisibility(View.GONE);
mSpaceTitleContent.setVisibility(View.GONE);
}
}
if (mBuilder.mPositiveButtonText == null && mBuilder.mNegativeButtonText == null) {
ViewUtils.setVisibility(mButtonsSingleLine, View.GONE);
mButtonsSingleLine.setVisibility(View.GONE);
} else {
if (mBuilder.mPositiveButtonText != null) {
mPositiveButton.setText(mBuilder.mPositiveButtonText);
mPositiveButton.setOnClickListener(this);
RippleSalon.addRipple(mPositiveButton, false);
} else {
ViewUtils.setVisibility(mPositiveButton, View.GONE);
ViewUtils.setVisibility(mSpacePositiveNegative, View.GONE);
mPositiveButton.setVisibility(View.GONE);
mSpacePositiveNegative.setVisibility(View.GONE);
}
if (mBuilder.mNegativeButtonText != null) {
mNegativeButton.setText(mBuilder.mNegativeButtonText);
mNegativeButton.setOnClickListener(this);
RippleSalon.addRipple(mNegativeButton, false);
} else {
ViewUtils.setVisibility(mNegativeButton, View.GONE);
ViewUtils.setVisibility(mSpacePositiveNegative, View.GONE);
mNegativeButton.setVisibility(View.GONE);
mSpacePositiveNegative.setVisibility(View.GONE);
}
}
@@ -27,8 +27,8 @@ import android.view.ViewTreeObserver;
import com.hippo.animation.ArgbEvaluator;
import com.hippo.animation.SimpleAnimatorListener;
import com.hippo.util.AnimationUtils;
import com.hippo.util.AssertUtils;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.AssertUtils;
import com.hippo.yorozuya.ViewUtils;
import java.util.HashSet;
import java.util.Set;
@@ -84,8 +84,8 @@ public class SimpleDialogCurtain extends Curtain {
AssertUtils.assertNotNull("Cushion view must not be null.", cushion);
AssertUtils.assertNotNull("Frame view must not be null.", frame);
ViewUtils.setVisibility(cushion, View.INVISIBLE);
ViewUtils.setVisibility(frame, View.INVISIBLE);
cushion.setVisibility(View.INVISIBLE);
frame.setVisibility(View.INVISIBLE);
// TODO addOnGlobalLayoutListener is not reliable
// TODO use isLayoutRequested
@@ -138,8 +138,8 @@ public class SimpleDialogCurtain extends Curtain {
mAnimatorSet.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
ViewUtils.setVisibility(cushion, View.VISIBLE);
ViewUtils.setVisibility(frame, View.VISIBLE);
cushion.setVisibility(View.VISIBLE);
frame.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
@@ -25,7 +25,7 @@ import android.view.ViewGroup;
import com.hippo.cardsalon.CardView;
import com.hippo.ehviewer.R;
import com.hippo.util.ResourcesUtils;
import com.hippo.yorozuya.ResourcesUtils;
public class SimpleDialogLayout extends ViewGroup {
@@ -24,8 +24,8 @@ import android.util.SparseArray;
import android.view.View;
import com.hippo.app.StatsActivity;
import com.hippo.util.IntIdGenerator;
import com.hippo.util.Log;
import com.hippo.yorozuya.IdGenerator;
import com.hippo.yorozuya.Say;
public abstract class StageActivity extends StatsActivity {
@@ -33,7 +33,7 @@ public abstract class StageActivity extends StatsActivity {
private static final String KEY_SCENEN_MANAGER_ID = "scene_manager_id";
private IntIdGenerator mActivityResultIdGenerator = IntIdGenerator.create();
private IdGenerator mActivityResultIdGenerator = new IdGenerator();
private SparseArray<Scene.ActivityResultListener> mActivityResultListenerMap =
new SparseArray<>();
@@ -53,7 +53,7 @@ public abstract class StageActivity extends StatsActivity {
} else {
int id = savedInstanceState.getInt(KEY_SCENEN_MANAGER_ID, -1);
if (id == -1) {
Log.e(TAG, "Can't get KEY_SCENEN_MANAGER_ID");
Say.e(TAG, "Can't get KEY_SCENEN_MANAGER_ID");
mSceneManager = SceneApplication.createSceneManager(this);
} else {
mSceneManager = SceneApplication.getSceneManager(this, id);
@@ -30,10 +30,10 @@ import android.widget.AbsoluteLayout;
import com.hippo.animation.ArgbEvaluator;
import com.hippo.animation.SimpleAnimatorListener;
import com.hippo.util.AnimationUtils;
import com.hippo.util.AssertUtils;
import com.hippo.util.Log;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.AssertUtils;
import com.hippo.widget.GlobalLayoutSet;
import com.hippo.yorozuya.Say;
import com.hippo.yorozuya.ViewUtils;
import java.util.HashSet;
import java.util.Set;
@@ -77,7 +77,7 @@ public class TransitionCurtain extends Curtain {
alphaAnim.setDuration(ANIMATE_TIME);
animatorCollection.add(alphaAnim);
} else {
Log.w(TAG, "Can't get enter scene content view");
Say.w(TAG, "Can't get enter scene content view");
}
GlobalLayoutSet globalLayoutSet = new GlobalLayoutSet();
@@ -92,16 +92,16 @@ public class TransitionCurtain extends Curtain {
final View enterView = enterViews[i];
final View exitView = exitViews[i];
if (enterView == null) {
Log.w(TAG, "Can't get enterView when open.");
Say.w(TAG, "Can't get enterView when open.");
continue;
}
if (exitView == null) {
Log.w(TAG, "Can't get exitView when open.");
Say.w(TAG, "Can't get exitView when open.");
continue;
}
// First make enter view invisible
ViewUtils.setVisibility(enterView, View.INVISIBLE);
enterView.setVisibility(View.INVISIBLE);
// Add item
TransitionItem item = new TransitionItem();
@@ -170,7 +170,7 @@ public class TransitionCurtain extends Curtain {
startWidth, startHeight, startloaction[0], startloaction[1]);
enterSceneView.addView(bmpView, lp);
ViewUtils.setVisibility(bmpView, View.INVISIBLE);
bmpView.setVisibility(View.INVISIBLE);
globalLayoutSet.addListenerToObserver(bmpView.getViewTreeObserver());
}
@@ -204,8 +204,8 @@ public class TransitionCurtain extends Curtain {
View exitView = item.exitView;
View bmpView = item.bmpView;
ViewUtils.setVisibility(exitView, View.INVISIBLE);
ViewUtils.setVisibility(bmpView, View.VISIBLE);
exitView.setVisibility(View.INVISIBLE);
bmpView.setVisibility(View.VISIBLE);
bmpView.setPivotX(0);
bmpView.setPivotY(0);
@@ -229,8 +229,8 @@ public class TransitionCurtain extends Curtain {
dispatchOpenFinished(mEnterScene, mExitScene);
hideSceneOnOpen(mExitScene);
for (TransitionItem item : mTransitionItemSet) {
ViewUtils.setVisibility(item.enterView, View.VISIBLE);
ViewUtils.setVisibility(item.exitView, View.VISIBLE);
item.enterView.setVisibility(View.VISIBLE);
item.exitView.setVisibility(View.VISIBLE);
ViewGroup enterSceneView = mEnterScene.getSceneView();
enterSceneView.removeView(item.bmpView);
@@ -265,7 +265,7 @@ public class TransitionCurtain extends Curtain {
alphaAnim.setDuration(ANIMATE_TIME);
animatorCollection.add(alphaAnim);
} else {
Log.w(TAG, "Can't get enter scene content view");
Say.w(TAG, "Can't get enter scene content view");
}
GlobalLayoutSet globalLayoutSet = new GlobalLayoutSet();
@@ -280,16 +280,16 @@ public class TransitionCurtain extends Curtain {
final View enterView = enterViews[i];
final View exitView = exitViews[i];
if (enterView == null) {
Log.w(TAG, "Can't get enterView when close");
Say.w(TAG, "Can't get enterView when close");
continue;
}
if (exitView == null) {
Log.w(TAG, "Can't get exitView when close");
Say.w(TAG, "Can't get exitView when close");
continue;
}
// First make enter view invisible
ViewUtils.setVisibility(enterView, View.INVISIBLE);
enterView.setVisibility(View.INVISIBLE);
// Add item
TransitionItem item = new TransitionItem();
@@ -357,7 +357,7 @@ public class TransitionCurtain extends Curtain {
startWidth, startHeight, startloaction[0], startloaction[1]);
exitSceneView.addView(bmpView, lp);
ViewUtils.setVisibility(bmpView, View.INVISIBLE);
bmpView.setVisibility(View.INVISIBLE);
globalLayoutSet.addListenerToObserver(bmpView.getViewTreeObserver());
}
@@ -391,8 +391,8 @@ public class TransitionCurtain extends Curtain {
View exitView = item.exitView;
View bmpView = item.bmpView;
ViewUtils.setVisibility(exitView, View.INVISIBLE);
ViewUtils.setVisibility(bmpView, View.VISIBLE);
exitView.setVisibility(View.INVISIBLE);
bmpView.setVisibility(View.VISIBLE);
bmpView.setPivotX(0);
bmpView.setPivotY(0);
@@ -415,8 +415,8 @@ public class TransitionCurtain extends Curtain {
public void onAnimationEnd(Animator animation) {
dispatchCloseFinished(mEnterScene, mExitScene);
for (TransitionItem item : mTransitionItemSet) {
ViewUtils.setVisibility(item.enterView, View.VISIBLE);
ViewUtils.setVisibility(item.exitView, View.VISIBLE);
item.enterView.setVisibility(View.VISIBLE);
item.exitView.setVisibility(View.VISIBLE);
ViewGroup exitSceneView = mExitScene.getSceneView();
exitSceneView.removeView(item.bmpView);
@@ -30,7 +30,6 @@ import com.hippo.rippleold.RippleSalon;
import com.hippo.scene.AppbarScene;
import com.hippo.scene.SimpleCurtain;
import com.hippo.scene.StageActivity;
import com.hippo.util.ViewUtils;
import com.hippo.widget.recyclerview.EasyRecyclerView;
import java.util.ArrayList;
@@ -115,7 +114,7 @@ public class PreferenceHeaderScene extends AppbarScene {
public void onBindViewHolder(HeaderHolder holder, int position) {
holder.icon.setImageDrawable(mHeaderList.get(position).getIcon());
holder.title.setText(mHeaderList.get(position).getTitle());
ViewUtils.setVisibility(holder.tileDivider, position == getItemCount() - 1 ? View.INVISIBLE : View.VISIBLE);
holder.tileDivider.setVisibility(position == getItemCount() - 1 ? View.INVISIBLE : View.VISIBLE);
}
@Override
@@ -24,8 +24,8 @@ import android.view.ViewGroup;
import com.hippo.ehviewer.R;
import com.hippo.rippleold.RippleSalon;
import com.hippo.scene.AppbarScene;
import com.hippo.util.ViewUtils;
import com.hippo.widget.recyclerview.EasyRecyclerView;
import com.hippo.yorozuya.ViewUtils;
import java.util.ArrayList;
import java.util.Collections;
@@ -1,36 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import android.os.Handler;
import android.os.Looper;
public class AppHandler extends Handler {
private static Handler sInstance;
public static Handler getInstance() {
if (sInstance == null) {
sInstance = new AppHandler(Looper.getMainLooper());
}
return sInstance;
}
public AppHandler(Looper mainLooper) {
super(mainLooper);
}
}
@@ -1,24 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
public class AssertError extends Error {
public AssertError(String detailMessage) {
super(detailMessage);
}
}
@@ -1,24 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
public class AssertException extends Exception {
public AssertException(String detailMessage) {
super(detailMessage);
}
}
@@ -1,85 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
public class AssertUtils {
public static void assertNull(String message, Object object) {
if (object != null) {
throw new AssertError(message);
}
}
public static void assertNotNull(String message, Object object) {
if (object == null) {
throw new AssertError(message);
}
}
public static void assertEquals(String message, int expected, int actual) {
if (expected != actual) {
throw new AssertError(message);
}
}
public static void assertNotEquals(String message, int expected, int actual) {
if (expected == actual) {
throw new AssertError(message);
}
}
public static void assertInstanceof(String message, Object obj, Class clazz) {
if (!clazz.isInstance(obj)) {
throw new AssertError(message);
}
}
public static void assertNullEx(String message, Object object)
throws AssertException {
if (object != null) {
throw new AssertException(message);
}
}
public static void assertNotNullEx(String message, Object object)
throws AssertException {
if (object == null) {
throw new AssertException(message);
}
}
public static void assertEqualsEx(String message, int expected, int actual)
throws AssertException {
if (expected != actual) {
throw new AssertException(message);
}
}
public static void assertNotEqualsEx(String message, int expected, int actual)
throws AssertException {
if (expected == actual) {
throw new AssertException(message);
}
}
public static void assertInstanceofEx(String message, Object obj, Class clazz)
throws AssertException {
if (!clazz.isInstance(obj)) {
throw new AssertException(message);
}
}
}
@@ -24,6 +24,7 @@ import android.support.annotation.Nullable;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.client.EhException;
import com.hippo.httpclient.ResponseCodeException;
import com.hippo.yorozuya.Say;
import org.apache.http.conn.ConnectTimeoutException;
@@ -34,6 +35,8 @@ import java.net.UnknownHostException;
public final class ExceptionUtils {
private static final String TAG = ExceptionUtils.class.getSimpleName();
public static @NonNull String getReadableString(Context context, Exception e) {
if (e instanceof ConnectTimeoutException ||
e instanceof SocketTimeoutException) {
@@ -55,7 +58,7 @@ public final class ExceptionUtils {
} else if (e instanceof EhException) {
return e.getMessage();
} else {
Log.d("Can't recognize this Exception", e);
Say.d(TAG, "Can't recognize this Exception", e);
return context.getString(R.string.em_unknown);
}
}
@@ -1,38 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import java.io.File;
public final class FileUtils {
public static boolean ensureFile(File file) {
return file != null && (!file.exists() || file.isFile());
}
public static boolean ensureDirectory(File file) {
if (file != null) {
if (file.exists()) {
return file.isDirectory();
} else {
return file.mkdirs();
}
} else {
return false;
}
}
}
@@ -1,33 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
public final class IntIdGenerator {
private int mId = 0;
private IntIdGenerator() {
// Empty
}
public synchronized int nextId() {
return mId++;
}
public static IntIdGenerator create() {
return new IntIdGenerator();
}
}
@@ -23,6 +23,8 @@ import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import com.hippo.widget.recyclerview.SimpleSmoothScroller;
import com.hippo.yorozuya.SimpleHandler;
import com.hippo.yorozuya.MathUtils;
public final class LayoutManagerUtils {
@@ -81,7 +83,7 @@ public final class LayoutManagerUtils {
public static void scrollToPositionProperly(final RecyclerView.LayoutManager layoutManager,
final Context context, final int position, final OnScrollToPositionListener listener) {
AppHandler.getInstance().postDelayed(new Runnable() {
SimpleHandler.getInstance().postDelayed(new Runnable() {
@Override
public void run() {
int first = getFirstVisibleItemPostion(layoutManager);
-419
View File
@@ -1,419 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import android.os.Process;
import com.hippo.ehviewer.AppConfig;
import com.hippo.ehviewer.BuildConfig;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
public class Log {
private static final String TAG = Log.class.getSimpleName();
private static final String NO_MESSAGE = "No Message";
private static final String LOG_FILENAME = "ehviewer.log";
private static final SaveLogThreadExecutor sSaveLogThreadPool;
private static final Pool<SaveMsgTask> sSaveLogTaskPool;
private static final DateFormat sDataFormat;
private static final File sLogFile;
private static final boolean sSupportSaveLog;
static {
sSaveLogThreadPool = new SaveLogThreadExecutor();
sSaveLogTaskPool = new Pool<>(10);
sDataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.ENGLISH);
sLogFile = AppConfig.getFileInAppDir(LOG_FILENAME);
sSupportSaveLog = FileUtils.ensureFile(sLogFile);
}
private static String avoidNull(String str) {
return str == null ? "null" : str;
}
public static void f(String msg) {
appendSaveLogTask(System.currentTimeMillis(), msg, null);
}
public static void f(String msg, Throwable tr) {
appendSaveLogTask(System.currentTimeMillis(), msg, tr);
}
private static void appendSaveLogTask(long time, String msg, Throwable tr) {
if (!sSupportSaveLog) {
return;
}
SaveMsgTask task = sSaveLogTaskPool.obtain();
if (task == null) {
task = new SaveMsgTask();
}
task.setParams(time, msg, tr);
try {
sSaveLogThreadPool.execute(task);
} catch (Throwable t) {
Log.e("Get error when save message to file", t);
}
}
private static class SaveLogThreadExecutor extends SerialThreadExecutor {
public SaveLogThreadExecutor() {
super(10L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(),
new PriorityThreadFactory("SaveLog", Process.THREAD_PRIORITY_BACKGROUND));
}
protected void afterExecute(Runnable r, Throwable t) {
if (r instanceof SaveMsgTask) {
SaveMsgTask task = (SaveMsgTask) r;
task.clear();
sSaveLogTaskPool.recycle(task);
}
}
}
private static class SaveMsgTask implements Runnable {
private long mTime;
private String mMsg;
private Throwable mTr;
public void clear() {
setParams(0, null, null);
}
public void setParams(long time, String msg, Throwable tr) {
mTime = time;
mMsg = msg;
mTr = tr;
}
@Override
public void run() {
FileWriter fw = null;
try {
fw = new FileWriter(sLogFile, true);
fw.append(sDataFormat.format(new Date(mTime))).append(" ").append(mMsg).append("\n");
if (mTr != null) {
fw.append(Log.getStackTraceString(mTr)).append("\n");
}
fw.flush(); // TODO Only do flush when the thread is about to close
} catch (IOException e) {
Log.e("Get error when save message to file", e);
Utils.closeQuietly(fw);
}
}
}
/**
* Call {@link android.util.Log#v(String, String)} with default tag.
* @param msg The message you would like logged.
*/
public static int v(String msg) {
return v(TAG, msg);
}
/**
* It is {@link android.util.Log#v(String, String)}, only work when debug.
* @param tag Used to identify the source of a log message. It usually identifies
* the class or activity where the log call occurs.
* @param msg The message you would like logged.
*/
public static int v(String tag, String msg) {
if (BuildConfig.DEBUG) {
return android.util.Log.v(tag, avoidNull(msg));
} else {
return 0;
}
}
/**
* Call {@link android.util.Log#v(String, String, Throwable)} with default tag
* and no message.
* @param tr An exception to log
*/
public static int v(Throwable tr) {
return v(TAG, NO_MESSAGE, tr);
}
/**
* Call {@link android.util.Log#v(String, String, Throwable)} with default tag.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static int v(String msg, Throwable tr) {
return v(TAG, msg, tr);
}
/**
* It is {@link android.util.Log#v(String, String, Throwable)}, only work when debug.
* @param tag Used to identify the source of a log message. It usually identifies
* the class or activity where the log call occurs.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static int v(String tag, String msg, Throwable tr) {
if (BuildConfig.DEBUG) {
return android.util.Log.v(tag, avoidNull(msg), tr);
} else {
return 0;
}
}
/**
* Call {@link android.util.Log#d(String, String)} with default tag.
* @param msg The message you would like logged.
*/
public static int d(String msg) {
return d(TAG, msg);
}
/**
* It is {@link android.util.Log#d(String, String)}, only work when debug.
* @param tag Used to identify the source of a log message. It usually identifies
* the class or activity where the log call occurs.
* @param msg The message you would like logged.
*/
public static int d(String tag, String msg) {
if (BuildConfig.DEBUG) {
return android.util.Log.d(tag, avoidNull(msg));
} else {
return 0;
}
}
/**
* Call {@link android.util.Log#d(String, String, Throwable)} with default tag
* and no message.
* @param tr An exception to log
*/
public static int d(Throwable tr) {
return d(TAG, NO_MESSAGE, tr);
}
/**
* Call {@link android.util.Log#d(String, String, Throwable)} with default tag.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static int d(String msg, Throwable tr) {
return d(TAG, msg, tr);
}
/**
* It is {@link android.util.Log#d(String, String, Throwable)}, only work when debug.
* @param tag Used to identify the source of a log message. It usually identifies
* the class or activity where the log call occurs.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static int d(String tag, String msg, Throwable tr) {
if (BuildConfig.DEBUG) {
return android.util.Log.d(tag, avoidNull(msg), tr);
} else {
return 0;
}
}
/**
* Call {@link android.util.Log#i(String, String)} with default tag.
* @param msg The message you would like logged.
*/
public static int i(String msg) {
return i(TAG, msg);
}
/**
* It is {@link android.util.Log#i(String, String)}, only work when debug.
* @param tag Used to identify the source of a log message. It usually identifies
* the class or activity where the log call occurs.
* @param msg The message you would like logged.
*/
public static int i(String tag, String msg) {
if (BuildConfig.DEBUG) {
return android.util.Log.i(tag, avoidNull(msg));
} else {
return 0;
}
}
/**
* Call {@link android.util.Log#i(String, String, Throwable)} with default tag
* and no message.
* @param tr An exception to log
*/
public static int i(Throwable tr) {
return i(TAG, NO_MESSAGE, tr);
}
/**
* Call {@link android.util.Log#i(String, String, Throwable)} with default tag.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static int i(String msg, Throwable tr) {
return i(TAG, msg, tr);
}
/**
* It is {@link android.util.Log#i(String, String, Throwable)}, only work when debug.
* @param tag Used to identify the source of a log message. It usually identifies
* the class or activity where the log call occurs.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static int i(String tag, String msg, Throwable tr) {
if (BuildConfig.DEBUG) {
return android.util.Log.i(tag, avoidNull(msg), tr);
} else {
return 0;
}
}
/**
* Call {@link android.util.Log#w(String, String)} with default tag.
* @param msg The message you would like logged.
*/
public static int w(String msg) {
return w(TAG, msg);
}
/**
* It is {@link android.util.Log#w(String, String)}, only work when debug.
* @param tag Used to identify the source of a log message. It usually identifies
* the class or activity where the log call occurs.
* @param msg The message you would like logged.
*/
public static int w(String tag, String msg) {
if (BuildConfig.DEBUG) {
return android.util.Log.w(tag, avoidNull(msg));
} else {
return 0;
}
}
/**
* Call {@link android.util.Log#w(String, String, Throwable)} with default tag
* and no message.
* @param tr An exception to log
*/
public static int w(Throwable tr) {
return w(TAG, NO_MESSAGE, tr);
}
/**
* Call {@link android.util.Log#w(String, String, Throwable)} with default tag.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static int w(String msg, Throwable tr) {
return w(TAG, msg, tr);
}
/**
* It is {@link android.util.Log#w(String, String, Throwable)}, only work when debug.
* @param tag Used to identify the source of a log message. It usually identifies
* the class or activity where the log call occurs.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static int w(String tag, String msg, Throwable tr) {
if (BuildConfig.DEBUG) {
return android.util.Log.w(tag, avoidNull(msg), tr);
} else {
return 0;
}
}
/**
* Call {@link android.util.Log#e(String, String)} with default tag.
* @param msg The message you would like logged.
*/
public static int e(String msg) {
return e(TAG, msg);
}
/**
* It is {@link android.util.Log#e(String, String)}, only work when debug.
* @param tag Used to identify the source of a log message. It usually identifies
* the class or activity where the log call occurs.
* @param msg The message you would like logged.
*/
public static int e(String tag, String msg) {
if (BuildConfig.DEBUG) {
return android.util.Log.e(tag, avoidNull(msg));
} else {
return 0;
}
}
/**
* Call {@link android.util.Log#e(String, String, Throwable)} with default tag
* and no message.
* @param tr An exception to log
*/
public static int e(Throwable tr) {
return e(TAG, NO_MESSAGE, tr);
}
/**
* Call {@link android.util.Log#e(String, String, Throwable)} with default tag.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static int e(String msg, Throwable tr) {
return e(TAG, msg, tr);
}
/**
* It is {@link android.util.Log#e(String, String, Throwable)}, only work when debug.
* @param tag Used to identify the source of a log message. It usually identifies
* the class or activity where the log call occurs.
* @param msg The message you would like logged.
* @param tr An exception to log
*/
public static int e(String tag, String msg, Throwable tr) {
if (BuildConfig.DEBUG) {
return android.util.Log.e(tag, avoidNull(msg), tr);
} else {
return 0;
}
}
/**
* It is {@link android.util.Log#getStackTraceString(Throwable)}.<br>
* Handy function to get a loggable stack trace from a Throwable
* @param tr An exception to log
*/
public static String getStackTraceString(Throwable tr) {
return android.util.Log.getStackTraceString(tr);
}
}
@@ -1,348 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import java.util.Random;
// Get most code from android.util.MathUtils
public final class MathUtils {
private static final Random sRandom = new Random();
private static final float DEG_TO_RAD = 3.1415926f / 180.0f;
private static final float RAD_TO_DEG = 180.0f / 3.1415926f;
public static float abs(float v) {
return v > 0 ? v : -v;
}
public static float log(float a) {
return (float) Math.log(a);
}
public static float exp(float a) {
return (float) Math.exp(a);
}
public static float pow(float a, float b) {
return (float) Math.pow(a, b);
}
public static float max(float a, float b) {
return a > b ? a : b;
}
public static float max(int a, int b) {
return a > b ? a : b;
}
public static float max(float a, float b, float c) {
return a > b ? (a > c ? a : c) : (b > c ? b : c);
}
public static float max(int a, int b, int c) {
return a > b ? (a > c ? a : c) : (b > c ? b : c);
}
public static float max(float... arg) {
int length = arg.length;
if (length <= 0) {
throw new IllegalArgumentException("Empty argument");
} else {
float n = arg[0];
float m;
for (int i = 1; i < length; i++) {
m = arg[i];
if (m > n)
n = m;
}
return n;
}
}
public static int max(int... arg) {
int length = arg.length;
if (length <= 0) {
throw new IllegalArgumentException("Empty argument");
} else {
int n = arg[0];
int m;
for (int i = 1; i < length; i++) {
m = arg[i];
if (m > n)
n = m;
}
return n;
}
}
public static float min(float a, float b) {
return a < b ? a : b;
}
public static float min(int a, int b) {
return a < b ? a : b;
}
public static float min(float a, float b, float c) {
return a < b ? (a < c ? a : c) : (b < c ? b : c);
}
public static float min(int a, int b, int c) {
return a < b ? (a < c ? a : c) : (b < c ? b : c);
}
public static float min(float... args) {
int length = args.length;
if (length <= 0) {
throw new IllegalArgumentException("Empty argument");
} else {
float n = args[0];
float m;
for (int i = 1; i < length; i++) {
m = args[i];
if (m < n)
n = m;
}
return n;
}
}
public static int min(int... args) {
int length = args.length;
if (length <= 0) {
throw new IllegalArgumentException("Empty argument");
} else {
int n = args[0];
int m;
for (int i = 1; i < length; i++) {
m = args[i];
if (m < n)
n = m;
}
return n;
}
}
public static float dist(float x1, float y1, float x2, float y2) {
final float x = (x2 - x1);
final float y = (y2 - y1);
return (float) Math.hypot(x, y);
}
public static float dist(float x1, float y1, float z1, float x2, float y2, float z2) {
final float x = (x2 - x1);
final float y = (y2 - y1);
final float z = (z2 - z1);
return (float) Math.sqrt(x * x + y * y + z * z);
}
public static boolean near(float x1, float y1, float x2, float y2, float slop) {
return dist(x1, y1, x2, y2) < slop;
}
public static boolean near(float x1, float y1, float z1, float x2, float y2, float z2, float slop) {
return dist(x1, y1, z1, x2, y2, z2) < slop;
}
public static float mag(float a, float b) {
return (float) Math.hypot(a, b);
}
public static float mag(float a, float b, float c) {
return (float) Math.sqrt(a * a + b * b + c * c);
}
public static float sq(float v) {
return v * v;
}
public static float radians(float degrees) {
return degrees * DEG_TO_RAD;
}
public static float degrees(float radians) {
return radians * RAD_TO_DEG;
}
public static float acos(float value) {
return (float) Math.acos(value);
}
public static float asin(float value) {
return (float) Math.asin(value);
}
public static float atan(float value) {
return (float) Math.atan(value);
}
public static float atan2(float a, float b) {
return (float) Math.atan2(a, b);
}
public static float tan(float angle) {
return (float) Math.tan(angle);
}
public static int lerp(int start, int stop, float amount) {
return start + (int) ((stop - start) * amount);
}
public static float lerp(float start, float stop, float amount) {
return start + (stop - start) * amount;
}
public static float norm(float start, float stop, float value) {
return (value - start) / (stop - start);
}
public static float map(float minStart, float minStop, float maxStart, float maxStop, float value) {
return maxStart + (maxStart - maxStop) * ((value - minStart) / (minStop - minStart));
}
/**
* Returns the input value x clamped to the range [min, max].
*
* @param x
* @param min
* @param max
* @return
*/
public static int clamp(int x, int min, int max) {
if (x > max) return max;
if (x < min) return min;
return x;
}
/**
* Returns the input value x clamped to the range [min, max].
*
* @param x
* @param min
* @param max
* @return
*/
public static float clamp(float x, float min, float max) {
if (x > max) return max;
if (x < min) return min;
return x;
}
/**
* Returns the input value x clamped to the range [min, max].
* @param x
* @param min
* @param max
* @return
*/
public static long clamp(long x, long min, long max) {
if (x > max) return max;
if (x < min) return min;
return x;
}
/**
* Returns the next power of two.
* Returns the input if it is already power of 2.
* Throws IllegalArgumentException if the input is <= 0 or
* the answer overflows.
*
* @param n
* @return
*/
public static int nextPowerOf2(int n) {
if (n <= 0 || n > (1 << 30)) throw new IllegalArgumentException("n is invalid: " + n);
n -= 1;
n |= n >> 16;
n |= n >> 8;
n |= n >> 4;
n |= n >> 2;
n |= n >> 1;
return n + 1;
}
/**
*
* @param a
* @param b
* @return
*/
public static int ceilDivide(int a, int b) {
return (a + b - 1) / b;
}
/**
* Return is a and b is in the same side to standard.
* If one of a and b equals standard, return true.
*
* @param a
* @param b
* @param standard
* @return
*/
public static boolean isSameSide(float a, float b, float standard) {
return (a >= standard && b >= standard) || (a <= standard && b <= standard);
}
/**
* Get coverage radius of a area
*
* @param w
* @param h
* @param x
* @param y
* @return
*/
public static float coverageRadius(float w, float h, float x, float y) {
float x2;
float y2;
if (x > w / 2) {
x2 = 0;
} else {
x2 = w;
}
if (y > h / 2) {
y2 = 0;
} else {
y2 = h;
}
return dist(x, y, x2, y2);
}
public static int random(int howbig) {
return (int) (sRandom.nextFloat() * howbig);
}
public static int random(int howsmall, int howbig) {
if (howsmall >= howbig)
return howsmall;
return (int) (sRandom.nextFloat() * (howbig - howsmall) + howsmall);
}
public static float random(float howbig) {
return sRandom.nextFloat() * howbig;
}
public static float random(float howsmall, float howbig) {
if (howsmall >= howbig)
return howsmall;
return sRandom.nextFloat() * (howbig - howsmall) + howsmall;
}
public static void randomSeed(long seed) {
sRandom.setSeed(seed);
}
}
@@ -1,86 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import android.util.SparseArray;
import java.util.HashSet;
import java.util.Set;
public class Messenger {
private IntIdGenerator mIdGenerator;
private SparseArray<Set<Receiver>> mReceiverSetMap;
private static Messenger sInstance;
public static Messenger getInstance() {
if (sInstance == null) {
sInstance = new Messenger();
}
return sInstance;
}
private Messenger() {
mIdGenerator = IntIdGenerator.create();
mReceiverSetMap = new SparseArray<>();
}
public int newId() {
return mIdGenerator.nextId();
}
public void notify(final int id, final Object obj) {
// Make sure do it in UI thread
AppHandler.getInstance().post(new Runnable() {
@Override
public void run() {
Set<Receiver> receiverSet = mReceiverSetMap.get(id);
if (receiverSet != null) {
for (Receiver receiver : receiverSet) {
receiver.onReceive(id, obj);
}
}
}
});
}
public void register(int id, Receiver receiver) {
Set<Receiver> receiverSet = mReceiverSetMap.get(id);
if (receiverSet == null) {
receiverSet = new HashSet<>();
mReceiverSetMap.put(id, receiverSet);
}
receiverSet.add(receiver);
}
public void unregister(int id, Receiver receiver) {
Set<Receiver> receiverSet = mReceiverSetMap.get(id);
if (receiverSet != null) {
receiverSet.remove(receiver);
if (receiverSet.isEmpty()) {
mReceiverSetMap.remove(id);
}
}
}
public interface Receiver {
void onReceive(final int id, final Object obj);
}
}
-137
View File
@@ -1,137 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class Pool<E> {
private static final int MAX_POOL_SIZE = 50;
private final Object mPoolSync = new Object();
private int mPoolMaxSize;
private int mPoolSize = 0;
private @Nullable Node<E> mFirstNode = null;
private @Nullable Node<E> mLastNode = null;
public Pool() {
this(MAX_POOL_SIZE);
}
public Pool(int size) {
if (size <= 0) {
throw new IllegalStateException("Pool max size must 1 or larger");
}
mPoolMaxSize = size;
}
/**
* @return null if no item in pool
*/
public @Nullable E obtain() {
synchronized (mPoolSync) {
if (mFirstNode != null && mFirstNode.value != null) {
Node<E> node = mFirstNode;
mFirstNode = node.next;
if (mFirstNode != null) {
mFirstNode.pre = null;
}
E e = node.value;
recycleNode(node);
mPoolSize--;
return e;
}
}
return null;
}
/**
* Add item to pool
*
* @param e the item
*/
public void recycle(@NonNull E e) {
synchronized (mPoolSync) {
if (mPoolSize < mPoolMaxSize) {
Node<E> node = obtainEmptyNode();
node.value = e;
node.next = mFirstNode;
if (mFirstNode != null) {
mFirstNode.pre = node;
}
mFirstNode = node;
mPoolSize++;
if (mLastNode == null) {
mLastNode = node;
}
}
}
}
private @NonNull Node<E> obtainEmptyNode() {
if (mLastNode == null || mLastNode.value != null) {
// No empty node
return new Node<>();
} else {
Node<E> node = mLastNode;
mLastNode = node.pre;
if (mLastNode == null) {
mFirstNode = null;
} else {
mLastNode.next = null;
}
node.pre = null;
return node;
}
}
private void recycleNode(@NonNull Node<E> node) {
if (mLastNode == null) {
node.value = null;
node.pre = null;
node.next = null;
mFirstNode = node;
mLastNode = node;
} else {
node.value = null;
mLastNode.next = node;
node.pre = mLastNode;
node.next = null;
mLastNode = node;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for(Node<E> node = mFirstNode; node != null; node = node.next) {
sb.append(node.value).append(';');
}
return sb.toString();
}
private static class Node<V> {
public @Nullable V value;
public @Nullable Node<V> pre;
public @Nullable Node<V> next;
}
}
@@ -1,48 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import android.os.Process;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
/**
* A thread factory that creates threads with a given thread priority.
*/
public class PriorityThreadFactory implements ThreadFactory {
private final int mPriority;
private final AtomicInteger mNumber = new AtomicInteger();
private final String mName;
public PriorityThreadFactory(String name, int priority) {
mName = name;
mPriority = priority;
}
@Override
public Thread newThread(Runnable r) {
return new Thread(r, mName + '-' + mNumber.getAndIncrement()) {
@Override
public void run() {
Process.setThreadPriority(mPriority);
super.run();
}
};
}
}
@@ -1,29 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import android.content.res.Resources;
import android.util.TypedValue;
public final class ResourcesUtils {
public static float getFloat(Resources resources, int resId) {
TypedValue outValue = new TypedValue();
resources.getValue(resId, outValue, true);
return outValue.getFloat();
}
}
@@ -1,125 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import android.support.annotation.NonNull;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SerialThreadExecutor implements Executor, Runnable {
private long mKeepAliveTime;
private BlockingQueue<Runnable> mWorkQueue;
private ThreadFactory mThreadFactory;
private transient Thread mThread;
private final Lock mThreadLock = new ReentrantLock();
private final Object mWaitLock = new Object();
public SerialThreadExecutor(long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
mKeepAliveTime = unit.toMillis(keepAliveTime);
mWorkQueue = workQueue;
mThreadFactory = threadFactory;
}
@Override
public void execute(@NonNull Runnable command) {
try {
mWorkQueue.put(command);
ensureThread();
} catch (Exception e) {
putFailed(command, e);
}
}
private void ensureThread() {
mThreadLock.lock();
if (mThread == null) {
mThread = mThreadFactory.newThread(this);
mThread.start();
} else {
synchronized (mWaitLock) {
mWaitLock.notifyAll();
}
}
mThreadLock.unlock();
}
protected void putFailed(@NonNull Runnable command, @NonNull Exception e) {
}
protected void beforeExecute(Thread t, Runnable r) {
}
protected void afterExecute(Runnable r, Throwable t) {
}
protected void beforeExcute() {
}
@Override
public void run() {
boolean hasWait = false;
for (;;) {
mThreadLock.lock();
if (mWorkQueue.isEmpty()) {
if (hasWait) {
mThread = null;
mThreadLock.unlock();
// Have waitted enough time
break;
} else {
hasWait = true;
synchronized (mWaitLock) {
mThreadLock.unlock();
try {
mWaitLock.wait(mKeepAliveTime);
} catch (InterruptedException e) {
// Empty
}
continue;
}
}
} else {
mThreadLock.unlock();
}
hasWait = false;
Runnable runnable = mWorkQueue.poll();
if (runnable != null) {
beforeExecute(mThread, runnable);
Throwable throwable = null;
try {
runnable.run();
} catch (Throwable tr) {
throwable = tr;
}
afterExecute(runnable, throwable);
}
}
}
}
@@ -1,90 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import android.content.Context;
import android.graphics.Color;
import com.hippo.ehviewer.R;
public class UiUtils {
/**
* dp conversion to pix
*
* @param context The context
* @param dp The value you want to conversion
* @return value in pix
*/
public static int dp2pix(Context context, float dp) {
return (int) (dp * context.getResources().getDisplayMetrics().density + 0.5f);
}
/**
* pix conversion to dp
*
* @param context The context
* @param pix The value you want to conversion
* @return value in dp
*/
public static float pix2dp(Context context, int pix) {
return pix / context.getResources().getDisplayMetrics().density;
}
/**
* sp conversion to pix
*
* @param sp The value you want to conversion
* @return value in pix
*/
public static int sp2pix(Context context, float sp) {
return (int) (sp * context.getResources().getDisplayMetrics().scaledDensity + 0.5f);
}
/**
* pix conversion to sp
*
* @param pix The value you want to conversion
* @return value in sp
*/
public static float pix2sp(Context context, float pix) {
return pix / context.getResources().getDisplayMetrics().scaledDensity;
}
/**
* get darker color of target color, alpha not change
* @param color the color you want to make it darker
* @return new darker color
*/
public static int getDarkerColor(int color) {
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
hsv[2] *= 0.9f;
return Color.HSVToColor(hsv);
}
/**
* Is this device is table.
* For sw600dp is true
*
* @param context the context
* @return true for table
*/
public static boolean isTable(Context context) {
return context.getResources().getBoolean(R.bool.is_table);
}
}
-811
View File
@@ -1,811 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.webkit.MimeTypeMap;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Locale;
public final class Utils {
@SuppressWarnings("unused")
private static String TAG = Utils.class.getSimpleName();
public static final DateFormat DATE_FORMATE_FOR_GALLERY = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.US);
public static final DateFormat DATE_FORMATE_FOR_UPDATE = new SimpleDateFormat("yyyyMMdd", Locale.US);
public static final String EMPTY_STRING = "";
/**
* Colse is. Don't worry about anything.
*
* @param is
*/
public static void closeQuietly(Closeable is) {
try {
if (is != null)
is.close();
} catch (IOException e) {
}
}
/**
* Put InputStream to File, default bufferSize is 512 * 1024
*
* @param is
* @param file
* @throws java.io.IOException
*/
public static void inputStream2File(InputStream is, File file) throws IOException {
OutputStream os = new FileOutputStream(file);
copy(is, os);
os.close();
}
/**
* Copy from is to os
*
* @param is
* @param os
* @throws java.io.IOException
*/
public static void copy(InputStream is, OutputStream os) throws IOException {
copy(is, os, 512 * 1024);
}
/**
* Copy from is to os
*
* @param is
* @param os
* @param size Buffer size
* @throws java.io.IOException
*/
public static void copy(InputStream is, OutputStream os, int size) throws IOException {
byte[] buffer = new byte[size];
int bytesRead;
while((bytesRead = is.read(buffer)) !=-1)
os.write(buffer, 0, bytesRead);
os.flush();
}
/**
* Get String from InputStream
*
* @param is
* @param charset
* @param size The InputStream size you estimate
* @return
*/
public static String inputStream2String(InputStream is, String charset, int size) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(size);
String str = null;
try {
copy(is, baos, 1024);
str = baos.toString(charset);
} catch (IOException e) {
e.printStackTrace();
} finally {
closeQuietly(baos);
}
return str;
}
/**
* Not work for dir, Copy from scr to dst, no matter dst exist or not.
*
* @param src
* @param dst
* @return True for success, false for fail
*/
public static boolean copyFile(File src, File dst) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(src);
fos = new FileOutputStream(dst);
copy(fis, fos);
} catch (Throwable e) {
return false;
} finally {
closeQuietly(fis);
closeQuietly(fos);
}
return true;
}
/**
* If you want to copy on new thread, use it to know
* success or not.
*/
public interface OnCopyFileOverListener {
void onCopyFileOver(boolean success, File src, File dst);
}
/**
* Copy file in new thread
*
* @param src
* @param dst
* @param l
*/
public static void copyFileInNewThread(final File src, final File dst, final OnCopyFileOverListener l) {
execute(false, new AsyncTask<Void, Void, Boolean>() {
@Override
protected Boolean doInBackground(Void... params) {
return copyFile(src, dst);
}
@Override
protected void onPostExecute(Boolean result) {
if (l != null)
l.onCopyFileOver(result, src, dst);
}
}, (Void[]) null);
}
/**
* Try to delete file or dir and it's children.
*
* @param file The file to deleted.
* @return True if file is delete, children included.
*/
public static boolean deleteFile(File file) {
if (file == null) {
return false;
}
boolean result = true;
File[] files = file.listFiles();
if (files != null) {
for (File f : files)
deleteFile(f);
}
if (file.exists()) {
// Avoid EBUSY (Device or resource busy) error
final File to = new File(file.getAbsolutePath()
+ System.currentTimeMillis());
if (file.renameTo(to))
result &= to.delete();
else
result &= file.delete();
}
return result;
}
/**
* If you want to copy on new thread, use it to know
* success or not.
*/
public interface OnDeleteFileOverListener {
void onDeleteFileOver(boolean success, File file);
}
/**
* Start a new thread to delete dir
*/
public static void deleteFileInNewThread(final File file, final OnDeleteFileOverListener l) {
execute(false, new AsyncTask<Void, Void, Boolean>() {
@Override
protected Boolean doInBackground(Void... params) {
return deleteFile(file);
}
@Override
protected void onPostExecute(Boolean result) {
if (l != null)
l.onDeleteFileOver(result, file);
}
}, (Void[]) null);
}
public static int getDateForUpdate() {
return Utils.parseIntSafely(DATE_FORMATE_FOR_UPDATE.format(new Date()), 0);
}
// http://stackoverflow.com/questions/3758606/
public static String humanReadableByteCount(long bytes, boolean si) {
int unit = si ? 1000 : 1024;
if (bytes < unit) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(unit));
char pre = "KMGTPE".charAt(exp-1);
return String.format("%.1f %cB", bytes / Math.pow(unit, exp), pre);
}
/**
* Execute an {@link android.os.AsyncTask} on a thread pool
*
* @param forceSerial True to force the task to run in serial order
* @param task Task to execute
* @param args Optional arguments to pass to
* {@link android.os.AsyncTask#execute(Object[])}
* @param <T> Task argument type
*/
@SafeVarargs
@SuppressLint("NewApi")
public static <T> void execute(final boolean forceSerial, final AsyncTask<T, ?, ?> task,
final T... args) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.DONUT) {
throw new UnsupportedOperationException(
"This class can only be used on API 4 and newer.");
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB || forceSerial) {
task.execute(args);
} else {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, args);
}
}
private static final String[] ESCAPE_CHARATER_LIST = {
"&amp;",
"&lt;",
"&gt;",
"&quot;",
"&#039;",
"&times;",
"&nbsp;"
};
private static final String[] UNESCAPE_CHARATER_LIST = {
"&",
"<",
">",
"\"",
"'",
"×",
" "
};
/**
* Mostly title and url need it
* @param str
* @return
*/
public static String unescapeXml(String str) {
return replaceEach(str, ESCAPE_CHARATER_LIST, UNESCAPE_CHARATER_LIST);
}
/**
* Make file name valid by removing invalid character and set max length
* @param name
* @return
*/
public static String standardizeFilename(String name) {
String result = name;
// Remove invaild char
result = result.replaceAll("[\\\\/:*?\"<>\\|]", "");
// Make sure size
if (result.length() > 255)
result = result.substring(0, 255);
// Avoid start with whitespace or end with whitespace
result = result.replaceAll("^[\\s]+", "").replace("[\\s]+$", "");
return result;
}
/**
* Joins the elements of the provided array into a single String
* containing the provided list of elements.
*
* @param array
* @param separator
* @return
*/
public static String join(final Object[] array,
final Object separator) {
final StringBuilder sb = new StringBuilder(array.length * 16);
for (int i = 0; i < array.length; i++) {
if (i != 0)
sb.append(separator);
sb.append(array[i]);
}
return sb.toString();
}
/**
* <p>
* Replaces all occurrences of Strings within another String.
* </p>
*
* <p>
* A {@code null} reference passed to this method is a no-op, or if
* any "search string" or "string to replace" is null, that replace will be
* ignored. This will not repeat. For repeating replaces, call the
* overloaded method.
* </p>
*
* <pre>
* StringUtils.replaceEach(null, *, *) = null
* StringUtils.replaceEach("", *, *) = ""
* StringUtils.replaceEach("aba", null, null) = "aba"
* StringUtils.replaceEach("aba", new String[0], null) = "aba"
* StringUtils.replaceEach("aba", null, new String[0]) = "aba"
* StringUtils.replaceEach("aba", new String[]{"a"}, null) = "aba"
* StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}) = "b"
* StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}) = "aba"
* StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}) = "wcte"
* (example of how it does not repeat)
* StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}) = "dcte"
* </pre>
*
* @param text
* text to search and replace in, no-op if null
* @param searchList
* the Strings to search for, no-op if null
* @param replacementList
* the Strings to replace them with, no-op if null
* @return the text with any replacements processed, {@code null} if
* null String input
* @throws IllegalArgumentException
* if the lengths of the arrays are not the same (null is ok,
* and/or size 0)
*/
// Get from org.apache.commons.lang3.StringUtils
public static String replaceEach(final String text, final String[] searchList, final String[] replacementList) {
return replaceEach(text, searchList, replacementList, false, 0);
}
/**
* <p>
* Replaces all occurrences of Strings within another String.
* </p>
*
* <p>
* A {@code null} reference passed to this method is a no-op, or if
* any "search string" or "string to replace" is null, that replace will be
* ignored.
* </p>
*
* <pre>
* StringUtils.replaceEach(null, *, *, *) = null
* StringUtils.replaceEach("", *, *, *) = ""
* StringUtils.replaceEach("aba", null, null, *) = "aba"
* StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
* StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
* StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
* StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
* StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
* StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}, *) = "wcte"
* (example of how it repeats)
* StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, false) = "dcte"
* StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, true) = "tcte"
* StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, *) = IllegalStateException
* </pre>
*
* @param text
* text to search and replace in, no-op if null
* @param searchList
* the Strings to search for, no-op if null
* @param replacementList
* the Strings to replace them with, no-op if null
* @param repeat if true, then replace repeatedly
* until there are no more possible replacements or timeToLive < 0
* @param timeToLive
* if less than 0 then there is a circular reference and endless
* loop
* @return the text with any replacements processed, {@code null} if
* null String input
* @throws IllegalStateException
* if the search is repeating and there is an endless loop due
* to outputs of one being inputs to another
* @throws IllegalArgumentException
* if the lengths of the arrays are not the same (null is ok,
* and/or size 0)
*/
// Get from org.apache.commons.lang3.StringUtils
private static String replaceEach(
final String text, final String[] searchList, final String[] replacementList, final boolean repeat, final int timeToLive) {
// mchyzer Performance note: This creates very few new objects (one major goal)
// let me know if there are performance requests, we can create a harness to measure
if (text == null || TextUtils.isEmpty(text) || searchList == null ||
searchList.length == 0 || replacementList == null || replacementList.length == 0) {
return text;
}
// if recursing, this shouldn't be less than 0
if (timeToLive < 0) {
throw new IllegalStateException("Aborting to protect against StackOverflowError - " +
"output of one loop is the input of another");
}
final int searchLength = searchList.length;
final int replacementLength = replacementList.length;
// make sure lengths are ok, these need to be equal
if (searchLength != replacementLength) {
throw new IllegalArgumentException("Search and Replace array lengths don't match: "
+ searchLength
+ " vs "
+ replacementLength);
}
// keep track of which still have matches
final boolean[] noMoreMatchesForReplIndex = new boolean[searchLength];
// index on index that the match was found
int textIndex = -1;
int replaceIndex = -1;
int tempIndex = -1;
// index of replace array that will replace the search string found
// NOTE: logic duplicated below START
for (int i = 0; i < searchLength; i++) {
if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
TextUtils.isEmpty(searchList[i]) || replacementList[i] == null) {
continue;
}
tempIndex = text.indexOf(searchList[i]);
// see if we need to keep searching for this
if (tempIndex == -1) {
noMoreMatchesForReplIndex[i] = true;
} else {
if (textIndex == -1 || tempIndex < textIndex) {
textIndex = tempIndex;
replaceIndex = i;
}
}
}
// NOTE: logic mostly below END
// no search strings found, we are done
if (textIndex == -1) {
return text;
}
int start = 0;
// get a good guess on the size of the result buffer so it doesn't have to double if it goes over a bit
int increase = 0;
// count the replacement text elements that are larger than their corresponding text being replaced
for (int i = 0; i < searchList.length; i++) {
if (searchList[i] == null || replacementList[i] == null) {
continue;
}
final int greater = replacementList[i].length() - searchList[i].length();
if (greater > 0) {
increase += 3 * greater; // assume 3 matches
}
}
// have upper-bound at 20% increase, then let Java take over
increase = Math.min(increase, text.length() / 5);
final StringBuilder buf = new StringBuilder(text.length() + increase);
while (textIndex != -1) {
for (int i = start; i < textIndex; i++) {
buf.append(text.charAt(i));
}
buf.append(replacementList[replaceIndex]);
start = textIndex + searchList[replaceIndex].length();
textIndex = -1;
replaceIndex = -1;
tempIndex = -1;
// find the next earliest match
// NOTE: logic mostly duplicated above START
for (int i = 0; i < searchLength; i++) {
if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
TextUtils.isEmpty(searchList[i]) || replacementList[i] == null) {
continue;
}
tempIndex = text.indexOf(searchList[i], start);
// see if we need to keep searching for this
if (tempIndex == -1) {
noMoreMatchesForReplIndex[i] = true;
} else {
if (textIndex == -1 || tempIndex < textIndex) {
textIndex = tempIndex;
replaceIndex = i;
}
}
}
// NOTE: logic duplicated above END
}
final int textLength = text.length();
for (int i = start; i < textLength; i++) {
buf.append(text.charAt(i));
}
final String result = buf.toString();
if (!repeat) {
return result;
}
return replaceEach(result, searchList, replacementList, repeat, timeToLive - 1);
}
/**
* 0 for false, Non 0 for true
*
* @param integer
* @return
*/
public static boolean int2boolean(int integer) {
return integer != 0;
}
/**
* false for 0, true for 1
*
* @param bool
* @return
*/
public static int boolean2int(boolean bool) {
return bool ? 1 : 0;
}
/**
* Returns the ASCII characters up to but not including the next "\r\n", or
* "\n".
*
* @throws java.io.EOFException if the stream is exhausted before the next
* newline character.
*/
public static String readAsciiLine(final InputStream in) throws IOException {
final StringBuilder result = new StringBuilder(80);
while (true) {
final int c = in.read();
if (c == -1) {
throw new EOFException();
} else if (c == '\n') {
break;
}
result.append((char)c);
}
final int length = result.length();
if (length > 0 && result.charAt(length - 1) == '\r') {
result.setLength(length - 1);
}
return result.toString();
}
/**
* Try to make dir exists
*
* @param dir
* @param force
*/
public static void ensureDir(File dir, boolean force) {
if (!dir.exists()) {
dir.mkdirs();
} else if (force && dir.isFile()) {
dir.delete();
dir.mkdirs();
}
}
/**
* Return true if point is in the rect
*
* @param area
* @param x
* @param y
* @return
*/
public static boolean isInArea(int[] area, int x, int y) {
if (area == null)
throw new NullPointerException("area == null");
if (area.length != 4)
throw new IllegalArgumentException(
"area's length should be 4, but it's length is " + area.length);
return x >= area[0] && x < area[2] && y >= area[1] && y < area[3];
}
/**
* Is color is opaque
*
* @param color
* @return
*/
// TODO put it to UiUtils.class
public static boolean isOpaque(int color) {
return color >>> 24 == 0xFF;
}
/**
* Throws AssertionError if the input is false.
* @param cond
*/
public static void assertTrue(boolean cond) {
if (!cond) {
throw new AssertionError();
}
}
/**
* vibrator
*
* @param context
* @param milliseconds Duration
*/
public static void vibrator(Context context, long milliseconds) {
// If user force disable vibrator permission, may throw error
try {
Vibrator v = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(milliseconds);
} catch (Throwable e) {
}
}
// Removes duplicate adjacent slashes and any trailing slash.
private static String fixSlashes(String origPath) {
// Remove duplicate adjacent slashes.
boolean lastWasSlash = false;
char[] newPath = origPath.toCharArray();
int length = newPath.length;
int newLength = 0;
for (int i = 0; i < length; ++i) {
char ch = newPath[i];
if (ch == '/') {
if (!lastWasSlash) {
newPath[newLength++] = File.separatorChar;
lastWasSlash = true;
}
} else {
newPath[newLength++] = ch;
lastWasSlash = false;
}
}
// Remove any trailing slash (unless this is the root of the file system).
if (lastWasSlash && newLength > 1) {
newLength--;
}
// Reuse the original string if possible.
return (newLength != length) ? new String(newPath, 0, newLength) : origPath;
}
// Joins two path components, adding a separator only if necessary.
public static String joinPath(String dirPath, String name) {
if (name == null) {
throw new NullPointerException("name == null");
}
if (dirPath == null || TextUtils.isEmpty(dirPath)) {
return fixSlashes(name);
} else if (TextUtils.isEmpty(name)) {
return fixSlashes(dirPath);
} else {
int prefixLength = dirPath.length();
boolean haveSlash = (prefixLength > 0 && dirPath.charAt(prefixLength - 1) == File.separatorChar);
if (!haveSlash) {
haveSlash = (name.length() > 0 && name.charAt(0) == File.separatorChar);
}
return fixSlashes(haveSlash ? (dirPath + name) : (dirPath + File.separatorChar + name));
}
}
public static int parseIntSafely(String str, int defaultValue) {
try {
return Integer.parseInt(str);
} catch (Throwable e) {
return defaultValue;
}
}
public static float parseFloatSafely(String str, float defaultValue) {
try {
return Float.parseFloat(str);
} catch (Throwable e) {
return defaultValue;
}
}
public static int[] toIntArray(Collection<? extends Number> collection) {
Object[] boxedArray = collection.toArray();
int len = boxedArray.length;
int[] array = new int[len];
for (int i = 0; i < len; i++) {
// checkNotNull for GWT (do not optimize)
array[i] = ((Number) (boxedArray[i])).intValue();
}
return array;
}
// Throws NullPointerException if the input is null.
public static <T> T checkNotNull(T object) {
if (object == null) throw new NullPointerException();
return object;
}
/**
* Get extension from target string, int lower case
*
* @param name
* @param defautl
* @return
*/
public static String getExtension(String name, String defautl) {
String ext = MimeTypeMap.getFileExtensionFromUrl(name);
if (TextUtils.isEmpty(ext))
ext = defautl;
return ext;
}
/**
* It will return null if can't find mime
*
* @param url
* @return
*/
public static String getMimeType(String url) {
String type = null;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension != null) {
MimeTypeMap mime = MimeTypeMap.getSingleton();
type = mime.getMimeTypeFromExtension(extension);
}
return type;
}
/**
* If get error return "";
*
* @param key
* @return
*/
public static String getSystemProperties(String key) {
try {
@SuppressWarnings("rawtypes")
Class c = Class.forName("android.os.SystemProperties");
@SuppressWarnings("unchecked")
Method m = c.getDeclaredMethod("get", String.class);
m.setAccessible(true);
String result = (String) m.invoke(null, key);
return result == null ? EMPTY_STRING : result;
} catch (Throwable e) {
return EMPTY_STRING;
}
}
public static boolean contain(@NonNull Object[] array, Object obj) {
for (Object o : array) {
if (o.equals(obj)) {
return true;
}
}
return false;
}
}
@@ -1,394 +0,0 @@
/*
* Copyright (C) 2015 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Build;
import android.support.annotation.Nullable;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
public final class ViewUtils {
public static final int MAX_SIZE = Integer.MAX_VALUE & ~(0x3 << 30);
/**
* Get view center location in window
*
* @param view the view to check
* @param location an array of two integers in which to hold the coordinates
*/
public static void getCenterInWindows(View view, int[] location) {
getLocationInWindow(view, location);
location[0] += view.getWidth() / 2;
location[1] += view.getHeight() / 2;
}
/**
* Get view location in window
*
* @param view the view to check
* @param location an array of two integers in which to hold the coordinates
*/
public static void getLocationInWindow(View view, int[] location) {
getLocationInAncestor(view, location, android.R.id.content);
}
public static void getCenterInAncestor(View view, int[] location, int ancestorId) {
getLocationInAncestor(view, location, ancestorId);
location[0] += view.getWidth() / 2;
location[1] += view.getHeight() / 2;
}
/**
* Get view location in ths ancestor
*
* @param view
* @param location
* @param ancestorId
*/
public static void getLocationInAncestor(View view, int[] location, int ancestorId) {
if (location == null || location.length < 2) {
throw new IllegalArgumentException(
"location must be an array of two integers");
}
float[] position = new float[2];
position[0] = view.getLeft();
position[1] = view.getTop();
ViewParent viewParent = view.getParent();
while (viewParent instanceof View) {
view = (View) viewParent;
if (view.getId() == ancestorId) {
break;
}
position[0] -= view.getScrollX();
position[1] -= view.getScrollY();
position[0] += view.getLeft();
position[1] += view.getTop();
viewParent = view.getParent();
}
location[0] = (int) (position[0] + 0.5f);
location[1] = (int) (position[1] + 0.5f);
}
public static void getCenterInAncestor(View view, int[] location, View ancestor) {
getLocationInAncestor(view, location, ancestor);
location[0] += view.getWidth() / 2;
location[1] += view.getHeight() / 2;
}
/**
* Get view location in ths ancestor
*
* @param view
* @param location
* @param ancestor
*/
public static void getLocationInAncestor(View view, int[] location, View ancestor) {
if (location == null || location.length < 2) {
throw new IllegalArgumentException(
"location must be an array of two integers");
}
float[] position = new float[2];
position[0] = view.getLeft();
position[1] = view.getTop();
ViewParent viewParent = view.getParent();
while (viewParent instanceof View) {
view = (View) viewParent;
if (viewParent == ancestor) {
break;
}
position[0] -= view.getScrollX();
position[1] -= view.getScrollY();
position[0] += view.getLeft();
position[1] += view.getTop();
viewParent = view.getParent();
}
location[0] = (int) (position[0] + 0.5f);
location[1] = (int) (position[1] + 0.5f);
}
/**
* Look for a ancestor view with the given id. If this view has the given
* id, return this view.
*
* @param view the view to start with
* @param id The id to search for.
* @return The view that has the given id in the hierarchy or null
*/
public static View getAncestor(View view, int id) {
if (view.getId() == id) {
return view;
}
ViewParent viewParent = view.getParent();
while (viewParent instanceof View) {
view = (View) viewParent;
if (view.getId() == id) {
return view;
}
viewParent = view.getParent();
}
return null;
}
/**
* Returns a bitmap showing a screenshot of the view passed in.
*
* @param v The view to get screenshot
* @return The screenshot
*/
public static Bitmap getBitmapFromView(View v) {
int width = v.getWidth();
int height = v.getHeight();
if (width == 0 && height == 0) {
width = v.getMeasuredWidth();
height = v.getMeasuredHeight();
}
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.translate(-v.getScrollX(), -v.getScrollY());
v.draw(canvas);
return bitmap;
}
/**
* Remove view from its parent
*
* @param view the view to remove
*/
public static void removeFromParent(View view) {
ViewParent vp = view.getParent();
if (vp instanceof ViewGroup)
((ViewGroup) vp).removeView(view);
}
/**
* Method that removes the support for HardwareAcceleration from a
* {@link android.view.View}.<br/>
* <br/>
* Check AOSP notice:<br/>
*
* <pre>
* 'ComposeShader can only contain shaders of different types (a BitmapShader and a
* LinearGradient for instance, but not two instances of BitmapShader)'. But, 'If your
* application is affected by any of these missing features or limitations, you can turn
* off hardware acceleration for just the affected portion of your application by calling
* setLayerType(View.LAYER_TYPE_SOFTWARE, null).'
* </pre>
*
* @param v
* The view
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static void removeHardwareAccelerationSupport(View v) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
if (v.getLayerType() != View.LAYER_TYPE_SOFTWARE) {
v.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static void addHardwareAccelerationSupport(View v) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
if (v.getLayerType() != View.LAYER_TYPE_HARDWARE) {
v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
}
}
public static void measureView(View v, int width, int height) {
int widthMeasureSpec;
int heightMeasureSpec;
if (width == ViewGroup.LayoutParams.WRAP_CONTENT)
widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
else
widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(Math.max(width, 0),
View.MeasureSpec.EXACTLY);
if (height == ViewGroup.LayoutParams.WRAP_CONTENT)
heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
else
heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(Math.max(height, 0),
View.MeasureSpec.EXACTLY);
v.measure(widthMeasureSpec, heightMeasureSpec);
}
/**
* Determine if the supplied view is under the given point in the
* parent view's coordinate system.
*
* @param view Child view of the parent to hit test
* @param x X position to test in the parent's coordinate system
* @param y Y position to test in the parent's coordinate system
* @return true if the supplied view is under the given point, false otherwise
*/
public static boolean isViewUnder(@Nullable View view, int x, int y) {
if (view == null || view.getVisibility() != View.VISIBLE) {
return false;
}
return x >= view.getLeft() &&
x < view.getRight() &&
y >= view.getTop() &&
y < view.getBottom();
}
/**
* Set the enabled state of this view.
*
* @param v the view to set the enabled state
* @param visibility One of {@link android.view.View#GONE},
* {@link android.view.View#INVISIBLE}, or {@link android.view.View#GONE}.
*/
public static void setVisibility(@Nullable View v, int visibility) {
if (v == null) {
return;
}
if (visibility != v.getVisibility()) {
v.setVisibility(visibility);
}
}
public static final int MEASURED_STATE_TOO_SMALL = 0x01000000;
public static final int MEASURED_STATE_MASK = 0xff000000;
/**
* Utility to reconcile a desired size and state, with constraints imposed
* by a MeasureSpec. Will take the desired size, unless a different size
* is imposed by the constraints. The returned value is a compound integer,
* with the resolved size in the MEASURED_SIZE_MASK bits and
* optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the resulting
* size is smaller than the size the view wants to be.
*
* @param size How big the view wants to be
* @param measureSpec Constraints imposed by the parent
* @return Size information bit mask as defined by
*/
public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
int result = size;
int specMode = View.MeasureSpec.getMode(measureSpec);
int specSize = View.MeasureSpec.getSize(measureSpec);
switch (specMode) {
case View.MeasureSpec.UNSPECIFIED:
result = size;
break;
case View.MeasureSpec.AT_MOST:
if (specSize < size) {
result = specSize | MEASURED_STATE_TOO_SMALL;
} else {
result = size;
}
break;
case View.MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result | (childMeasuredState&MEASURED_STATE_MASK);
}
/**
* Utility to return a default size. Uses the supplied size if the
* MeasureSpec imposed no constraints. Will get suitable if allowed
* by the MeasureSpec.
*
* @param size Default size for this view
* @param measureSpec Constraints imposed by the parent
* @return The size this view should be.
*/
public static int getSuitableSize(int size, int measureSpec) {
int result = size;
int specMode = View.MeasureSpec.getMode(measureSpec);
int specSize = View.MeasureSpec.getSize(measureSpec);
switch (specMode) {
case View.MeasureSpec.UNSPECIFIED:
result = size;
break;
case View.MeasureSpec.EXACTLY:
result = specSize;
break;
case View.MeasureSpec.AT_MOST:
result = size == 0 ? specSize : size;
}
return result;
}
/**
* removeOnGlobalLayoutListener
*
* @param vto
* @param l
*/
public static void removeOnGlobalLayoutListener(ViewTreeObserver vto,
ViewTreeObserver.OnGlobalLayoutListener l) {
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
vto.removeGlobalOnLayoutListener(l);
} else {
vto.removeOnGlobalLayoutListener(l);
}
}
/**
* Get index in parent
*
* @param view The view
* @return The index
*/
public static int getIndexInParent(View view) {
ViewParent parent = view.getParent();
if (parent instanceof ViewGroup) {
ViewGroup viewParent = (ViewGroup) parent;
int count = viewParent.getChildCount();
for (int i = 0; i < count; i++) {
View v = viewParent.getChildAt(i);
if (v == view) {
return i;
}
}
}
return -1;
}
public static void transformPointToViewLocal(float[] point, View parent, View child) {
point[0] += parent.getScrollX() - child.getLeft();
point[1] += parent.getScrollY() - child.getTop();
}
}
@@ -36,7 +36,7 @@ import com.hippo.ehviewer.R;
import com.hippo.hotspot.HotspotTouchHelper;
import com.hippo.hotspot.Hotspotable;
import com.hippo.util.AnimationUtils;
import com.hippo.util.MathUtils;
import com.hippo.yorozuya.MathUtils;
public class CheckTextView extends TextView implements OnClickListener, Hotspotable {
@@ -20,11 +20,11 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import com.hippo.ehviewer.R;
import com.hippo.util.MathUtils;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.MathUtils;
/**
* aspect is width / height
@@ -290,8 +290,8 @@ public class FixedAspectImageView extends ImageView {
w = Math.max(w, getSuggestedMinimumWidth());
h = Math.max(h, getSuggestedMinimumHeight());
widthSize = ViewUtils.resolveSizeAndState(w, widthMeasureSpec, 0);
heightSize = ViewUtils.resolveSizeAndState(h, heightMeasureSpec, 0);
widthSize = View.resolveSizeAndState(w, widthMeasureSpec, 0);
heightSize = View.resolveSizeAndState(h, heightMeasureSpec, 0);
}
setMeasuredDimension(widthSize, heightSize);
@@ -31,8 +31,9 @@ import android.util.AttributeSet;
import android.view.View;
import com.hippo.ehviewer.R;
import com.hippo.util.UiUtils;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.ColorUtils;
import com.hippo.yorozuya.LayoutUtils;
import com.hippo.yorozuya.ViewUtils;
public class FloatingActionButton extends View {
@@ -168,14 +169,14 @@ public class FloatingActionButton extends View {
private GasketDrawerOld(View view, int color) {
Context context = view.getContext();
mShadowRadious = UiUtils.dp2pix(context, 3);
mShadowOffsetY = UiUtils.dp2pix(context, 1);
mShadowRadious = LayoutUtils.dp2pix(context, 3);
mShadowOffsetY = LayoutUtils.dp2pix(context, 1);
mGasketPadding = mShadowRadious + mShadowOffsetY;
mView = view;
mBounds = new RectF();
mColor = color;
mDarkerColor = UiUtils.getDarkerColor(color);
mDarkerColor = ColorUtils.getDarkerColor(color);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
mPaint.setColor(mColor);
mPaint.setStyle(Paint.Style.FILL);
@@ -233,7 +234,7 @@ public class FloatingActionButton extends View {
@Override
public void setColor(int color) {
mColor = color;
mDarkerColor = UiUtils.getDarkerColor(color);
mDarkerColor = ColorUtils.getDarkerColor(color);
updateColor();
}
}
@@ -256,12 +257,12 @@ public class FloatingActionButton extends View {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public GasketDrawerLollipop(View view, int color) {
mElevation = UiUtils.dp2pix(view.getContext(), 4);
mElevation = LayoutUtils.dp2pix(view.getContext(), 4);
mView = view;
mColor = color;
int darkColor = UiUtils.getDarkerColor(color);
int darkColor = ColorUtils.getDarkerColor(color);
mGradientDrawable = new GradientDrawable();
mGradientDrawable.setShape(GradientDrawable.OVAL);
mGradientDrawable.setColor(new ColorStateList(STATES,
@@ -286,7 +287,7 @@ public class FloatingActionButton extends View {
public void setColor(int color) {
if (mColor != color) {
mColor = color;
int darkColor = UiUtils.getDarkerColor(color);
int darkColor = ColorUtils.getDarkerColor(color);
mGradientDrawable.setColor(new ColorStateList(STATES,
new int[] {darkColor, darkColor, darkColor, color}));
}
@@ -18,7 +18,7 @@ package com.hippo.widget;
import android.view.ViewTreeObserver;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.ViewUtils;
public class GlobalLayoutSet {
@@ -23,8 +23,8 @@ import android.view.View;
import android.view.ViewGroup;
import com.hippo.ehviewer.R;
import com.hippo.util.MathUtils;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.MathUtils;
import com.hippo.yorozuya.ViewUtils;
/**
* not scrollable
@@ -27,7 +27,6 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.hippo.ehviewer.R;
import com.hippo.util.ViewUtils;
public class Snackbar extends LinearLayout {
@@ -78,13 +77,13 @@ public class Snackbar extends LinearLayout {
if (TextUtils.isEmpty(actionText)) {
mActionTxt.setOnClickListener(null);
mActionTxt.setClickable(false);
ViewUtils.setVisibility(mSpace, View.GONE);
ViewUtils.setVisibility(mActionTxt, View.GONE);
mSpace.setVisibility(View.GONE);
mActionTxt.setVisibility(View.GONE);
} else {
mActionTxt.setText(actionText);
mActionTxt.setOnClickListener(action);
ViewUtils.setVisibility(mSpace, View.VISIBLE);
ViewUtils.setVisibility(mActionTxt, View.VISIBLE);
mSpace.setVisibility(View.VISIBLE);
mActionTxt.setVisibility(View.VISIBLE);
}
}
}
@@ -43,8 +43,8 @@ import android.view.accessibility.AccessibilityEvent;
import android.widget.Checkable;
import com.hippo.util.DrawableUtils;
import com.hippo.util.MathUtils;
import com.hippo.util.ViewUtils;
import com.hippo.yorozuya.MathUtils;
import com.hippo.yorozuya.ViewUtils;
/**
* Add setOnItemClickListener, setOnItemLongClickListener and setChoiceMode for