Add Yorozuya
This commit is contained in:
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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 = {
|
||||
"&",
|
||||
"<",
|
||||
">",
|
||||
""",
|
||||
"'",
|
||||
"×",
|
||||
" "
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
Reference in new issue
Block a user