Fix deprecated codes

This commit is contained in:
NekoInverter committed 2021-01-24 17:28:16 +08:00
1 parent 9128fdb523
commit d12961418a
51 files changed
+157 -1314

No files matched your search

@@ -18,6 +18,7 @@ package com.hippo.easyrecyclerview;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
@@ -28,6 +29,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.hippo.ehviewer.R;
@@ -223,11 +225,11 @@ public class FastScroller extends View {
mOnScrollChangeListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
updatePosition(true);
invalidate();
}
@@ -314,6 +316,7 @@ public class FastScroller extends View {
canvas.restoreToCount(saved);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!mDraggable || getVisibility() != VISIBLE || mRecyclerView == null || mHandlerHeight == INVALID) {
@@ -24,6 +24,8 @@ import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
public class HandlerDrawable extends Drawable {
private int mColor = Color.BLACK;
@@ -37,7 +39,7 @@ public class HandlerDrawable extends Drawable {
}
@Override
public void draw(Canvas canvas) {
public void draw(@NonNull Canvas canvas) {
int width = getBounds().width();
int height = getBounds().height();
@@ -81,9 +81,7 @@ public final class LayoutManagerUtils {
int direction = 0;
try {
direction = (Integer) sCsdfp.invoke(staggeredGridLayoutManager, targetPosition);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
@@ -108,21 +106,18 @@ public final class LayoutManagerUtils {
public static void scrollToPositionProperly(final RecyclerView.LayoutManager layoutManager,
final Context context, final int position, final OnScrollToPositionListener listener) {
SimpleHandler.getInstance().postDelayed(new Runnable() {
@Override
public void run() {
int first = getFirstVisibleItemPosition(layoutManager);
int last = getLastVisibleItemPosition(layoutManager);
int offset = Math.abs(position - first);
int max = last - first;
if (offset < max && max > 0) {
smoothScrollToPosition(layoutManager, context, position,
MathUtils.lerp(100, 25, (offset / max)));
} else {
scrollToPositionWithOffset(layoutManager, position, 0);
if (listener != null) {
listener.onScrollToPosition(position);
}
SimpleHandler.getInstance().postDelayed(() -> {
int first = getFirstVisibleItemPosition(layoutManager);
int last = getLastVisibleItemPosition(layoutManager);
int offset = Math.abs(position - first);
int max = last - first;
if (offset < max && max > 0) {
smoothScrollToPosition(layoutManager, context, position,
MathUtils.lerp(100, 25, (offset / max)));
} else {
scrollToPositionWithOffset(layoutManager, position, 0);
if (listener != null) {
listener.onScrollToPosition(position);
}
}
}, 200);
@@ -1,49 +0,0 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.easyrecyclerview;
import android.graphics.Rect;
import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
public class RawMarginItemDecoration extends RecyclerView.ItemDecoration {
private int mMarginLeft;
private int mMarginTop;
private int mMarginRight;
private int mMarginBottom;
public RawMarginItemDecoration(int marginLeft, int marginTop,
int marginRight, int marginBottom) {
setMargin(marginLeft, marginTop, marginRight, marginBottom);
}
public void setMargin(int marginLeft, int marginTop,
int marginRight, int marginBottom) {
mMarginLeft = marginLeft;
mMarginTop = marginTop;
mMarginRight = marginRight;
mMarginBottom = marginBottom;
}
@Override
public void getItemOffsets(Rect outRect, View view,
RecyclerView parent, RecyclerView.State state) {
outRect.set(mMarginLeft, mMarginTop, mMarginRight, mMarginBottom);
}
}
@@ -281,7 +281,7 @@ public class Hosts {
if (cursor.moveToNext()) {
String[] ips = SqlUtils.getString(cursor, COLUMN_IP, null).split("\\+");
List<InetAddress> addresses = new ArrayList<>();
for (String ip: ips) {
for (String ip : ips) {
addresses.add(toInetAddress(host, ip));
}
return addresses;
@@ -35,9 +35,7 @@ public class ImageBitmapHelper implements ValueHelper<ImageBitmap> {
try {
isPipe.obtain();
return ImageBitmap.decode(isPipe.open());
} catch (OutOfMemoryError e) {
return null;
} catch (IOException e) {
} catch (OutOfMemoryError | IOException e) {
return null;
} finally {
isPipe.close();
@@ -18,6 +18,8 @@ package com.hippo.ehviewer.client;
import android.content.Context;
import androidx.annotation.NonNull;
import com.hippo.network.CookieRepository;
import java.util.ArrayList;
@@ -84,8 +86,9 @@ public class EhCookieStore extends CookieRepository {
contains(url, KEY_IPD_PASS_HASH);
}
@NonNull
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
public List<Cookie> loadForRequest(@NonNull HttpUrl url) {
List<Cookie> cookies = super.loadForRequest(url);
boolean checkTips = domainMatch(url, EhUrl.DOMAIN_E);
@@ -27,7 +27,6 @@ import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.R;
import com.hippo.util.ExceptionUtils;
import com.hippo.util.IoThreadPoolExecutor;
import com.hippo.util.TextUrl;
import com.hippo.yorozuya.FileUtils;
import com.hippo.yorozuya.IOUtils;
@@ -37,6 +36,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
@@ -85,13 +85,13 @@ public class EhTagDatabase {
buffer.append(tmp[0]);
buffer.append("\r");
try {
buffer.append(new String(Base64.decode(tmp[1], Base64.DEFAULT), TextUrl.UTF_8));
buffer.append(new String(Base64.decode(tmp[1], Base64.DEFAULT), StandardCharsets.UTF_8));
} catch (Exception e) {
buffer.append(tmp[1]);
}
buffer.append("\n");
}
byte[] b = buffer.toString().getBytes(TextUrl.UTF_8);
byte[] b = buffer.toString().getBytes(StandardCharsets.UTF_8);
int totalBytes = b.length;
tags = new byte[totalBytes];
System.arraycopy(b, 0, tags, 0, totalBytes);
@@ -146,9 +146,7 @@ public class EhTagDatabase {
digest.update(buffer, 0, n);
}
return digest.digest();
} catch (IOException e) {
return null;
} catch (NoSuchAlgorithmException e) {
} catch (IOException | NoSuchAlgorithmException e) {
return null;
}
}
@@ -309,7 +307,7 @@ public class EhTagDatabase {
}
public String getTranslation(String tag) {
return search(tags, tag.getBytes(TextUrl.UTF_8));
return search(tags, tag.getBytes(StandardCharsets.UTF_8));
}
@Nullable
@@ -368,7 +366,7 @@ public class EhTagDatabase {
} else if (compare > 0) {
low = start + end + 1;
} else {
return new String(tags, start + middle + 1, end - middle - 1, TextUrl.UTF_8);
return new String(tags, start + middle + 1, end - middle - 1, StandardCharsets.UTF_8);
}
}
return null;
@@ -404,10 +402,10 @@ public class EhTagDatabase {
byte[] hintBytes = new byte[end - middle - 1];
System.arraycopy(tags, start + middle + 1, hintBytes, 0, end - middle - 1);
String hint = new String(hintBytes, TextUrl.UTF_8);
String hint = new String(hintBytes, StandardCharsets.UTF_8);
byte[] tagBytes = new byte[middle];
System.arraycopy(tags, start + 1, tagBytes, 0, middle);
String tag = new String(tagBytes, TextUrl.UTF_8);
String tag = new String(tagBytes, StandardCharsets.UTF_8);
int index = tag.indexOf(':');
boolean keywordMatches;
if (index == -1 || index >= tag.length() - 1 || keyword.length() > 2) {
@@ -16,8 +16,9 @@
package com.hippo.ehviewer.ui;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
@@ -32,6 +33,8 @@ import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -39,7 +42,6 @@ import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.core.view.WindowCompat;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
@@ -73,13 +75,13 @@ import com.hippo.ehviewer.ui.scene.WarningScene;
import com.hippo.ehviewer.ui.scene.WebViewSignInScene;
import com.hippo.ehviewer.widget.EhDrawerLayout;
import com.hippo.io.UniFileInputStreamPipe;
import com.hippo.network.Network;
import com.hippo.scene.Announcer;
import com.hippo.scene.SceneFragment;
import com.hippo.scene.StageActivity;
import com.hippo.unifile.UniFile;
import com.hippo.util.BitmapUtils;
import com.hippo.util.ClipboardUtil;
import com.hippo.widget.DrawerView;
import com.hippo.widget.LoadImageView;
import com.hippo.yorozuya.IOUtils;
import com.hippo.yorozuya.SimpleHandler;
@@ -93,12 +95,7 @@ import java.io.OutputStream;
public final class MainActivity extends StageActivity
implements NavigationView.OnNavigationItemSelectedListener {
private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0;
private static final int REQUEST_CODE_SETTINGS = 0;
private static final String KEY_NAV_CHECKED_ITEM = "nav_checked_item";
private static final String KEY_CLIP_TEXT_HASH_CODE = "clip_text_hash_code";
static {
registerLaunchMode(SecurityScene.class, SceneFragment.LAUNCH_MODE_SINGLE_TASK);
@@ -119,6 +116,13 @@ public final class MainActivity extends StageActivity
registerLaunchMode(ProgressScene.class, SceneFragment.LAUNCH_MODE_STANDARD);
}
ActivityResultLauncher<Intent> settingsLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == RESULT_OK) {
refreshTopScene();
}
});
/*---------------
Whole life cycle
---------------*/
@@ -127,7 +131,7 @@ public final class MainActivity extends StageActivity
@Nullable
private NavigationView mNavView;
@Nullable
private MaterialCardView mRightDrawer;
private DrawerView mRightDrawer;
@Nullable
private LoadImageView mAvatar;
@Nullable
@@ -139,7 +143,7 @@ public final class MainActivity extends StageActivity
return R.id.fragment_container;
}
@Nullable
@NonNull
@Override
protected Announcer getLaunchAnnouncer() {
if (!TextUtils.isEmpty(Settings.getSecurity())) {
@@ -247,7 +251,7 @@ public final class MainActivity extends StageActivity
builder.setKeyword(intent.getStringExtra(Intent.EXTRA_TEXT));
startScene(processAnnouncer(GalleryListScene.getStartAnnouncer(builder)));
return true;
} else if (type.startsWith("image/")) {
} else if (type != null && type.startsWith("image/")) {
Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (null != uri) {
UniFile file = UniFile.fromUri(this, uri);
@@ -307,17 +311,21 @@ public final class MainActivity extends StageActivity
mDrawerLayout = (EhDrawerLayout) ViewUtils.$$(this, R.id.draw_view);
mNavView = (NavigationView) ViewUtils.$$(this, R.id.nav_view);
mRightDrawer = (MaterialCardView) ViewUtils.$$(this, R.id.right_drawer);
mRightDrawer = (DrawerView) ViewUtils.$$(this, R.id.right_drawer);
View headerLayout = mNavView.getHeaderView(0);
mAvatar = (LoadImageView) ViewUtils.$$(headerLayout, R.id.avatar);
mDisplayName = (TextView) ViewUtils.$$(headerLayout, R.id.display_name);
ViewUtils.$$(headerLayout, R.id.night_mode).setOnClickListener(v -> {
int theme = (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_YES) > 0 ? AppCompatDelegate.MODE_NIGHT_NO : AppCompatDelegate.MODE_NIGHT_YES;
AppCompatDelegate.setDefaultNightMode(theme);
Settings.putTheme(theme);
if (Settings.getTheme() != AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) {
Settings.putTheme(theme);
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
findViewById(R.id.fragment_container).setFitsSystemWindows(true);
}
updateProfile();
@@ -327,8 +335,8 @@ public final class MainActivity extends StageActivity
if (savedInstanceState == null) {
checkDownloadLocation();
if (Settings.getCellularNetworkWarning()) {
checkCellularNetwork();
if (Settings.getMeteredNetworkWarning()) {
checkMeteredNetwork();
}
} else {
onRestore(savedInstanceState);
@@ -350,9 +358,19 @@ public final class MainActivity extends StageActivity
.show();
}
private void checkCellularNetwork() {
if (Network.getActiveNetworkType(this) == ConnectivityManager.TYPE_MOBILE) {
showTip(R.string.cellular_network_warning, BaseScene.LENGTH_SHORT);
private void checkMeteredNetwork() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm.isActiveNetworkMetered()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && mDrawerLayout != null) {
Snackbar.make(mDrawerLayout, R.string.metered_network_warning, Snackbar.LENGTH_LONG)
.setAction(R.string.settings, v -> {
Intent panelIntent = new Intent(android.provider.Settings.Panel.ACTION_INTERNET_CONNECTIVITY);
startActivity(panelIntent);
})
.show();
} else {
showTip(R.string.metered_network_warning, BaseScene.LENGTH_LONG);
}
}
}
@@ -361,7 +379,7 @@ public final class MainActivity extends StageActivity
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
outState.putInt(KEY_NAV_CHECKED_ITEM, mNavCheckedItem);
}
@@ -446,18 +464,6 @@ public final class MainActivity extends StageActivity
Settings.putClipboardTextHashCode(hashCode);
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE) {
if (grantResults.length == 1 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, R.string.you_rejected_me, Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
@Override
public void onSceneViewCreated(SceneFragment scene, Bundle savedInstanceState) {
super.onSceneViewCreated(scene, savedInstanceState);
@@ -465,6 +471,7 @@ public final class MainActivity extends StageActivity
createDrawerView(scene);
}
@SuppressLint("RtlHardcoded")
public void createDrawerView(SceneFragment scene) {
if (scene instanceof BaseScene && mRightDrawer != null && mDrawerLayout != null) {
BaseScene baseScene = (BaseScene) scene;
@@ -521,14 +528,6 @@ public final class MainActivity extends StageActivity
}
}
public int getDrawerLockMode(int edgeGravity) {
if (mDrawerLayout != null) {
return mDrawerLayout.getDrawerLockMode(edgeGravity);
} else {
return DrawerLayout.LOCK_MODE_UNLOCKED;
}
}
public void setDrawerLockMode(int lockMode, int edgeGravity) {
if (mDrawerLayout != null) {
mDrawerLayout.setDrawerLockMode(lockMode, edgeGravity);
@@ -585,6 +584,7 @@ public final class MainActivity extends StageActivity
}
}
@SuppressLint("RtlHardcoded")
@Override
public void onBackPressed() {
if (mDrawerLayout != null && (mDrawerLayout.isDrawerOpen(Gravity.LEFT) ||
@@ -632,7 +632,7 @@ public final class MainActivity extends StageActivity
startScene(new Announcer(DownloadsScene.class));
} else if (id == R.id.nav_settings) {
Intent intent = new Intent(this, SettingsActivity.class);
startActivityForResult(intent, REQUEST_CODE_SETTINGS);
settingsLauncher.launch(intent);
}
if (id != R.id.nav_stub && mDrawerLayout != null) {
@@ -642,20 +642,6 @@ public final class MainActivity extends StageActivity
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_SETTINGS:
if (RESULT_OK == resultCode) {
refreshTopScene();
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
public void setDrawerGestureBlocker(EhDrawerLayout.GestureBlocker gestureBlocker) {
if (mDrawerLayout != null) {
mDrawerLayout.setGestureBlocker(gestureBlocker);
@@ -18,6 +18,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -32,7 +33,6 @@ import com.hippo.easyrecyclerview.LinearDividerItemDecoration;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.client.EhFilter;
import com.hippo.ehviewer.dao.Filter;
import com.hippo.util.DrawableManager;
import com.hippo.view.ViewTransition;
import com.hippo.yorozuya.LayoutUtils;
import com.hippo.yorozuya.ViewUtils;
@@ -66,7 +66,7 @@ public class FilterFragment extends BaseFragment {
mViewTransition = new ViewTransition(recyclerView, tip);
FloatingActionButton fab = view.findViewById(R.id.fab);
Drawable drawable = DrawableManager.getVectorDrawable(requireActivity(), R.drawable.big_filter);
Drawable drawable = ContextCompat.getDrawable(requireActivity(), R.drawable.big_filter);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
@@ -18,6 +18,7 @@ package com.hippo.ehviewer.ui.scene;
import android.content.Context;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -31,7 +32,6 @@ import com.hippo.ehviewer.R;
import com.hippo.ehviewer.Settings;
import com.hippo.ehviewer.ui.MainActivity;
import com.hippo.text.Html;
import com.hippo.text.LinkMovementMethod2;
import com.hippo.yorozuya.ViewUtils;
public class AnalyticsScene extends SolidScene implements View.OnClickListener {
@@ -57,7 +57,7 @@ public class AnalyticsScene extends SolidScene implements View.OnClickListener {
TextView text = (TextView) ViewUtils.$$(view, R.id.text);
text.setText(Html.fromHtml(getString(R.string.analytics_explain)));
text.setMovementMethod(LinkMovementMethod2.getInstance());
text.setMovementMethod(LinkMovementMethod.getInstance());
mReject.setOnClickListener(this);
mAccept.setOnClickListener(this);
@@ -95,7 +95,6 @@ import com.hippo.io.UniFileInputStreamPipe;
import com.hippo.scene.Announcer;
import com.hippo.streampipe.InputStreamPipe;
import com.hippo.unifile.UniFile;
import com.hippo.util.DrawableManager;
import com.hippo.util.IoThreadPoolExecutor;
import com.hippo.view.ViewTransition;
import com.hippo.widget.FabLayout;
@@ -341,7 +340,7 @@ public class DownloadsScene extends ToolbarScene
AssertUtils.assertNotNull(content);
Resources resources = context.getResources();
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_download);
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.big_download);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
@@ -38,6 +38,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -75,7 +76,6 @@ import com.hippo.ehviewer.widget.SearchBar;
import com.hippo.scene.Announcer;
import com.hippo.scene.SceneFragment;
import com.hippo.util.AppHelper;
import com.hippo.util.DrawableManager;
import com.hippo.widget.ContentLayout;
import com.hippo.widget.FabLayout;
import com.hippo.widget.SearchBarMover;
@@ -276,7 +276,7 @@ public class FavoritesScene extends BaseScene implements
mLeftDrawable = new DrawerArrowDrawable(context, AttrResources.getAttrColor(context, android.R.attr.colorControlNormal));
mSearchBar.setLeftDrawable(mLeftDrawable);
mSearchBar.setRightDrawable(DrawableManager.getVectorDrawable(context, R.drawable.v_magnify_x24));
mSearchBar.setRightDrawable(ContextCompat.getDrawable(context, R.drawable.v_magnify_x24));
mSearchBar.setHelper(this);
mSearchBar.setAllowEmptySearch(false);
updateSearchBar();
@@ -33,6 +33,7 @@ import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
import android.text.style.StyleSpan;
import android.text.style.URLSpan;
import android.text.util.Linkify;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -45,6 +46,8 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.core.text.util.LinkifyCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -70,10 +73,8 @@ import com.hippo.scene.SceneFragment;
import com.hippo.text.Html;
import com.hippo.text.URLImageGetter;
import com.hippo.util.ClipboardUtil;
import com.hippo.util.DrawableManager;
import com.hippo.util.ExceptionUtils;
import com.hippo.util.ReadableTime;
import com.hippo.util.TextUrl;
import com.hippo.view.ViewTransition;
import com.hippo.widget.FabLayout;
import com.hippo.widget.LinkifyTextView;
@@ -213,12 +214,12 @@ public final class GalleryCommentsScene extends ToolbarScene
Resources resources = getResources();
int paddingBottomFab = resources.getDimensionPixelOffset(R.dimen.gallery_padding_bottom_fab);
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_sad_pandroid);
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.big_sad_pandroid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
mSendDrawable = DrawableManager.getVectorDrawable(context, R.drawable.v_send_dark_x24);
mPencilDrawable = DrawableManager.getVectorDrawable(context, R.drawable.v_pencil_dark_x24);
mSendDrawable = ContextCompat.getDrawable(context, R.drawable.v_send_dark_x24);
mPencilDrawable = ContextCompat.getDrawable(context, R.drawable.v_pencil_dark_x24);
mAdapter = new CommentAdapter();
mRecyclerView.setAdapter(mAdapter);
@@ -902,7 +903,9 @@ public final class GalleryCommentsScene extends ToolbarScene
ssb.append("\n\n").append(ss);
}
return TextUrl.handleTextUrl(ssb);
LinkifyCompat.addLinks(ssb, Linkify.WEB_URLS);
return ssb;
}
public void bind(GalleryComment value) {
@@ -106,7 +106,6 @@ import com.hippo.scene.TransitionHelper;
import com.hippo.text.Html;
import com.hippo.text.URLImageGetter;
import com.hippo.util.AppHelper;
import com.hippo.util.DrawableManager;
import com.hippo.util.ExceptionUtils;
import com.hippo.util.ReadableTime;
import com.hippo.view.ViewTransition;
@@ -531,7 +530,7 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene
}
});
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_sad_pandroid);
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.big_sad_pandroid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
mTip.setCompoundDrawables(null, drawable, null, null);
mTip.setOnClickListener(this);
@@ -748,7 +747,7 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene
private void setActionDrawable(@Nullable TextView text, @DrawableRes int resId) {
if (text == null) return;
Context context = text.getContext();
Drawable drawable = DrawableManager.getVectorDrawable(context, resId);
Drawable drawable = ContextCompat.getDrawable(context, resId);
if (drawable == null) return;
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
text.setCompoundDrawables(null, drawable, null, null);
@@ -50,6 +50,7 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -101,7 +102,6 @@ import com.hippo.ehviewer.widget.SearchLayout;
import com.hippo.scene.Announcer;
import com.hippo.scene.SceneFragment;
import com.hippo.util.AppHelper;
import com.hippo.util.DrawableManager;
import com.hippo.util.ExceptionUtils;
import com.hippo.view.BringOutTransition;
import com.hippo.view.ViewTransition;
@@ -1719,7 +1719,7 @@ public final class GalleryListScene extends BaseScene
@Override
public CharSequence getText(TextView textView) {
if (textView.getId() == android.R.id.text1) {
Drawable bookImage = DrawableManager.getVectorDrawable(textView.getContext(), R.drawable.v_book_open_x24);
Drawable bookImage = ContextCompat.getDrawable(textView.getContext(), R.drawable.v_book_open_x24);
SpannableStringBuilder ssb = new SpannableStringBuilder(" ");
ssb.append(getString(R.string.gallery_list_search_bar_open_gallery));
int imageSize = (int) (textView.getTextSize() * 1.25);
@@ -33,6 +33,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
@@ -73,7 +74,6 @@ import com.hippo.ehviewer.ui.dialog.SelectItemWithIconAdapter;
import com.hippo.ehviewer.widget.SimpleRatingView;
import com.hippo.scene.Announcer;
import com.hippo.scene.SceneFragment;
import com.hippo.util.DrawableManager;
import com.hippo.view.ViewTransition;
import com.hippo.widget.LoadImageView;
import com.hippo.widget.recyclerview.AutoStaggeredGridLayoutManager;
@@ -197,7 +197,7 @@ public class HistoryScene extends ToolbarScene {
AssertUtils.assertNotNull(context);
Resources resources = context.getResources();
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_history);
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.big_history);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
tip.setCompoundDrawables(null, drawable, null, null);
@@ -26,6 +26,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.R;
@@ -34,7 +35,6 @@ import com.hippo.ehviewer.client.EhRequest;
import com.hippo.ehviewer.ui.MainActivity;
import com.hippo.scene.Announcer;
import com.hippo.scene.SceneFragment;
import com.hippo.util.DrawableManager;
import com.hippo.util.ExceptionUtils;
import com.hippo.view.ViewTransition;
import com.hippo.yorozuya.AssertUtils;
@@ -166,7 +166,7 @@ public final class ProgressScene extends BaseScene implements View.OnClickListen
Context context = getContext();
AssertUtils.assertNotNull(context);
Drawable drawable = DrawableManager.getVectorDrawable(context, R.drawable.big_sad_pandroid);
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.big_sad_pandroid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
mTip.setCompoundDrawables(null, drawable, null, null);
mTip.setOnClickListener(this);
@@ -43,6 +43,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.tabs.TabLayout;
import com.hippo.easyrecyclerview.EasyRecyclerView;
import com.hippo.easyrecyclerview.MarginItemDecoration;
import com.hippo.easyrecyclerview.SimpleHolder;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.client.data.ListUrlBuilder;
import com.hippo.ehviewer.client.exception.EhException;
@@ -317,12 +318,6 @@ public class SearchLayout extends EasyRecyclerView implements CompoundButton.OnC
void onSelectImage();
}
private static class SimpleHolder extends RecyclerView.ViewHolder {
public SimpleHolder(View itemView) {
super(itemView);
}
}
private class SearchAdapter extends EasyRecyclerView.Adapter<SimpleHolder> {
@Override
@@ -20,7 +20,6 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowInsets;
import android.widget.LinearLayout;
import android.widget.SeekBar;
@@ -30,7 +29,7 @@ import androidx.annotation.NonNull;
import com.hippo.ehviewer.R;
import com.hippo.yorozuya.ViewUtils;
public class SeekBarPanel extends LinearLayout implements View.OnApplyWindowInsetsListener {
public class SeekBarPanel extends LinearLayout {
private SeekBar mSeekBar;
private final int[] mLocation = new int[2];
@@ -51,7 +50,6 @@ public class SeekBarPanel extends LinearLayout implements View.OnApplyWindowInse
protected void onFinishInflate() {
super.onFinishInflate();
mSeekBar = (SeekBar) ViewUtils.$$(this, R.id.seek_bar);
setOnApplyWindowInsetsListener(this);
}
@SuppressLint("ClickableViewAccessibility")
@@ -71,8 +69,7 @@ public class SeekBarPanel extends LinearLayout implements View.OnApplyWindowInse
}
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
setPadding(insets.getSystemWindowInsetLeft(), 0, insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
return insets.consumeSystemWindowInsets();
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(insets.getSystemWindowInsetLeft(), 0, insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()));
}
}
@@ -23,8 +23,9 @@ import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import androidx.core.content.ContextCompat;
import com.hippo.ehviewer.R;
import com.hippo.util.DrawableManager;
import com.hippo.yorozuya.MathUtils;
/**
@@ -58,9 +59,9 @@ public class SimpleRatingView extends View {
private void init(Context context) {
Resources resources = context.getResources();
mStarDrawable = DrawableManager.getVectorDrawable(context, R.drawable.v_star_x16);
mStarHalfDrawable = DrawableManager.getVectorDrawable(context, R.drawable.v_star_half_x16);
mStarOutlineDrawable = DrawableManager.getVectorDrawable(context, R.drawable.v_star_outline_x16);
mStarDrawable = ContextCompat.getDrawable(context, R.drawable.v_star_x16);
mStarHalfDrawable = ContextCompat.getDrawable(context, R.drawable.v_star_half_x16);
mStarOutlineDrawable = ContextCompat.getDrawable(context, R.drawable.v_star_outline_x16);
mRatingSize = resources.getDimensionPixelOffset(R.dimen.rating_size);
mRatingInterval = resources.getDimensionPixelOffset(R.dimen.rating_interval);
@@ -121,8 +121,7 @@ class CookieDatabase {
Map<String, CookieSet> map = new HashMap<>();
List<Long> toRemove = new ArrayList<>();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_COOKIE + ";", null);
try {
try (Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_COOKIE + ";", null)) {
while (cursor.moveToNext()) {
long id = SqlUtils.getLong(cursor, COLUMN_ID, 0);
Cookie cookie = getCookie(cursor, now);
@@ -143,8 +142,6 @@ class CookieDatabase {
toRemove.add(id);
}
}
} finally {
cursor.close();
}
// Remove invalid or expired cookie
@@ -22,11 +22,12 @@ package com.hippo.network;
import android.content.Context;
import androidx.annotation.NonNull;
import com.hippo.yorozuya.ObjectUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
@@ -153,12 +154,7 @@ public class CookieRepository implements CookieJar {
// RFC 6265 Section-5.4 step 2, sort the cookie-list
// Cookies with longer paths are listed before cookies with shorter paths.
// Ignore creation-time, we don't store them.
Collections.sort(accepted, new Comparator<Cookie>() {
@Override
public int compare(Cookie o1, Cookie o2) {
return o2.path().length() - o1.path().length();
}
});
Collections.sort(accepted, (o1, o2) -> o2.path().length() - o1.path().length());
return accepted;
}
@@ -185,14 +181,15 @@ public class CookieRepository implements CookieJar {
}
@Override
public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
public void saveFromResponse(@NonNull HttpUrl httpUrl, List<Cookie> list) {
for (Cookie cookie : list) {
addCookie(cookie);
}
}
@NonNull
@Override
public List<Cookie> loadForRequest(HttpUrl httpUrl) {
public List<Cookie> loadForRequest(@NonNull HttpUrl httpUrl) {
return getCookies(httpUrl);
}
}
@@ -78,7 +78,7 @@ public abstract class DialogPreference extends Preference implements
public DialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr, 0);
init(context, attrs, defStyleAttr, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
@@ -1,344 +0,0 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.preference;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.AttributeSet;
import androidx.annotation.ArrayRes;
import androidx.appcompat.app.AlertDialog;
import com.hippo.ehviewer.R;
public class ListPreference extends DialogPreference {
private CharSequence[] mEntries;
private CharSequence[] mEntryValues;
private String mValue;
private String mSummary;
private int mClickedDialogEntryIndex;
private boolean mValueSet;
public ListPreference(Context context) {
super(context);
init(context, null, 0, 0);
}
public ListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0, 0);
}
public ListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr, 0);
}
private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
setNegativeButtonText(android.R.string.cancel);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ListPreference, defStyleAttr, defStyleRes);
mEntries = a.getTextArray(R.styleable.ListPreference_entries);
mEntryValues = a.getTextArray(R.styleable.ListPreference_entryValues);
a.recycle();
/* Retrieve the Preference summary attribute since it's private
* in the Preference class.
*/
a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.summary}, defStyleAttr, defStyleRes);
mSummary = a.getString(0);
a.recycle();
}
/**
* The list of entries to be shown in the list in subsequent dialogs.
*
* @return The list as an array.
*/
public CharSequence[] getEntries() {
return mEntries;
}
/**
* Sets the human-readable entries to be shown in the list. This will be
* shown in subsequent dialogs.
* <p>
* Each entry must have a corresponding index in
* {@link #setEntryValues(CharSequence[])}.
*
* @param entries The entries.
* @see #setEntryValues(CharSequence[])
*/
public void setEntries(CharSequence[] entries) {
mEntries = entries;
}
/**
* @param entriesResId The entries array as a resource.
* @see #setEntries(CharSequence[])
*/
public void setEntries(@ArrayRes int entriesResId) {
setEntries(getContext().getResources().getTextArray(entriesResId));
}
/**
* Returns the array of values to be saved for the preference.
*
* @return The array of values.
*/
public CharSequence[] getEntryValues() {
return mEntryValues;
}
/**
* The array to find the value to save for a preference when an entry from
* entries is selected. If a user clicks on the second item in entries, the
* second item in this array will be saved to the preference.
*
* @param entryValues The array to be used as values to save for the preference.
*/
public void setEntryValues(CharSequence[] entryValues) {
mEntryValues = entryValues;
}
/**
* @param entryValuesResId The entry values array as a resource.
* @see #setEntryValues(CharSequence[])
*/
public void setEntryValues(@ArrayRes int entryValuesResId) {
setEntryValues(getContext().getResources().getTextArray(entryValuesResId));
}
/**
* Returns the summary of this ListPreference. If the summary
* has a {@linkplain java.lang.String#format String formatting}
* marker in it (i.e. "%s" or "%1$s"), then the current entry
* value will be substituted in its place.
*
* @return the summary with appropriate string substitution
*/
@Override
public CharSequence getSummary() {
final CharSequence entry = getEntry();
if (mSummary == null) {
return super.getSummary();
} else {
return String.format(mSummary, entry == null ? "" : entry);
}
}
/**
* Sets the summary for this Preference with a CharSequence.
* If the summary has a
* {@linkplain java.lang.String#format String formatting}
* marker in it (i.e. "%s" or "%1$s"), then the current entry
* value will be substituted in its place when it's retrieved.
*
* @param summary The summary for the preference.
*/
@Override
public void setSummary(CharSequence summary) {
super.setSummary(summary);
if (summary == null && mSummary != null) {
mSummary = null;
} else if (summary != null && !summary.equals(mSummary)) {
mSummary = summary.toString();
}
}
/**
* Returns the value of the key. This should be one of the entries in
* {@link #getEntryValues()}.
*
* @return The value of the key.
*/
public String getValue() {
return mValue;
}
/**
* Sets the value of the key. This should be one of the entries in
* {@link #getEntryValues()}.
*
* @param value The value to set for the key.
*/
public void setValue(String value) {
// Always persist/notify the first time.
final boolean changed = !TextUtils.equals(mValue, value);
if (changed || !mValueSet) {
mValue = value;
mValueSet = true;
persistString(value);
if (changed) {
notifyChanged();
}
}
}
/**
* Returns the entry corresponding to the current value.
*
* @return The entry corresponding to the current value, or null.
*/
public CharSequence getEntry() {
int index = getValueIndex();
return index >= 0 && mEntries != null ? mEntries[index] : null;
}
/**
* Returns the index of the given value (in the entry values array).
*
* @param value The value whose index should be returned.
* @return The index of the value, or -1 if not found.
*/
public int findIndexOfValue(String value) {
if (value != null && mEntryValues != null) {
for (int i = mEntryValues.length - 1; i >= 0; i--) {
if (mEntryValues[i].equals(value)) {
return i;
}
}
}
return -1;
}
private int getValueIndex() {
return findIndexOfValue(mValue);
}
/**
* Sets the value to the given index from the entry values.
*
* @param index The index of the value to set.
*/
public void setValueIndex(int index) {
if (mEntryValues != null) {
setValue(mEntryValues[index].toString());
}
}
@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
super.onPrepareDialogBuilder(builder);
if (mEntries == null || mEntryValues == null) {
throw new IllegalStateException(
"ListPreference requires an entries array and an entryValues array.");
}
mClickedDialogEntryIndex = getValueIndex();
builder.setSingleChoiceItems(mEntries, mClickedDialogEntryIndex,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
mClickedDialogEntryIndex = which;
/*
* Clicking on an item simulates the positive button
* click, and dismisses the dialog.
*/
ListPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
dialog.dismiss();
}
});
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult && mClickedDialogEntryIndex >= 0 && mEntryValues != null) {
String value = mEntryValues[mClickedDialogEntryIndex].toString();
if (callChangeListener(value)) {
setValue(value);
}
}
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getString(index);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue);
}
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (isPersistent()) {
// No need to save instance state since it's persistent
return superState;
}
final SavedState myState = new SavedState(superState);
myState.value = getValue();
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !state.getClass().equals(SavedState.class)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
setValue(myState.value);
}
private static class SavedState extends BaseSavedState {
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
String value;
public SavedState(Parcel source) {
super(source);
value = source.readString();
}
public SavedState(Parcelable superState) {
super(superState);
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(value);
}
}
}
@@ -78,7 +78,7 @@ public class MessagePreference extends DialogPreference {
if (mDialogMessageLinkify) {
final View messageView = dialog.findViewById(android.R.id.message);
if (null != messageView && messageView instanceof TextView) {
if (messageView instanceof TextView) {
((TextView) messageView).setMovementMethod(LinkMovementMethod.getInstance());
}
}
@@ -1,271 +0,0 @@
/*
* Copyright (C) 2006 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.text;
import android.text.Layout;
import android.text.NoCopySpan;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.MovementMethod;
import android.text.method.ScrollingMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import com.hippo.ehviewer.UrlOpener;
/**
* A movement method that traverses links in the text buffer and scrolls if necessary.
* Supports clicking on links with DPad Center or Enter.
*/
public class LinkMovementMethod2 extends ScrollingMovementMethod {
private static final int CLICK = 1;
private static final int UP = 2;
private static final int DOWN = 3;
private static final Object FROM_BELOW = new NoCopySpan.Concrete();
private static LinkMovementMethod2 sInstance;
private LinkMovementMethod2() {
}
public static MovementMethod getInstance() {
if (sInstance == null)
sInstance = new LinkMovementMethod2();
return sInstance;
}
@Override
public boolean canSelectArbitrarily() {
return true;
}
@Override
protected boolean handleMovementKey(TextView widget, Spannable buffer, int keyCode,
int movementMetaState, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
if (event.getAction() == KeyEvent.ACTION_DOWN &&
event.getRepeatCount() == 0 && action(CLICK, widget, buffer)) {
return true;
}
}
break;
}
return super.handleMovementKey(widget, buffer, keyCode, movementMetaState, event);
}
@Override
protected boolean up(TextView widget, Spannable buffer) {
if (action(UP, widget, buffer)) {
return true;
}
return super.up(widget, buffer);
}
@Override
protected boolean down(TextView widget, Spannable buffer) {
if (action(DOWN, widget, buffer)) {
return true;
}
return super.down(widget, buffer);
}
@Override
protected boolean left(TextView widget, Spannable buffer) {
if (action(UP, widget, buffer)) {
return true;
}
return super.left(widget, buffer);
}
@Override
protected boolean right(TextView widget, Spannable buffer) {
if (action(DOWN, widget, buffer)) {
return true;
}
return super.right(widget, buffer);
}
private boolean action(int what, TextView widget, Spannable buffer) {
Layout layout = widget.getLayout();
int padding = widget.getTotalPaddingTop() +
widget.getTotalPaddingBottom();
int areatop = widget.getScrollY();
int areabot = areatop + widget.getHeight() - padding;
int linetop = layout.getLineForVertical(areatop);
int linebot = layout.getLineForVertical(areabot);
int first = layout.getLineStart(linetop);
int last = layout.getLineEnd(linebot);
ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class);
int a = Selection.getSelectionStart(buffer);
int b = Selection.getSelectionEnd(buffer);
int selStart = Math.min(a, b);
int selEnd = Math.max(a, b);
if (selStart < 0) {
if (buffer.getSpanStart(FROM_BELOW) >= 0) {
selStart = selEnd = buffer.length();
}
}
if (selStart > last)
selStart = selEnd = Integer.MAX_VALUE;
if (selEnd < first)
selStart = selEnd = -1;
switch (what) {
case CLICK:
if (selStart == selEnd) {
return false;
}
ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class);
if (link.length != 1)
return false;
link[0].onClick(widget);
break;
case UP:
int beststart, bestend;
beststart = -1;
bestend = -1;
for (int i = 0; i < candidates.length; i++) {
int end = buffer.getSpanEnd(candidates[i]);
if (end < selEnd || selStart == selEnd) {
if (end > bestend) {
beststart = buffer.getSpanStart(candidates[i]);
bestend = end;
}
}
}
if (beststart >= 0) {
Selection.setSelection(buffer, bestend, beststart);
return true;
}
break;
case DOWN:
beststart = Integer.MAX_VALUE;
bestend = Integer.MAX_VALUE;
for (int i = 0; i < candidates.length; i++) {
int start = buffer.getSpanStart(candidates[i]);
if (start > selStart || selStart == selEnd) {
if (start < beststart) {
beststart = start;
bestend = buffer.getSpanEnd(candidates[i]);
}
}
}
if (bestend < Integer.MAX_VALUE) {
Selection.setSelection(buffer, beststart, bestend);
return true;
}
break;
}
return false;
}
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer,
MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
ClickableSpan span = link[0];
if (span instanceof URLSpan) {
UrlOpener.openUrl(widget.getContext(), ((URLSpan) span).getURL(), true);
} else {
span.onClick(widget);
}
} else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
}
return true;
} else {
Selection.removeSelection(buffer);
}
}
return super.onTouchEvent(widget, buffer, event);
}
@Override
public void initialize(TextView widget, Spannable text) {
Selection.removeSelection(text);
text.removeSpan(FROM_BELOW);
}
@Override
public void onTakeFocus(TextView view, Spannable text, int dir) {
Selection.removeSelection(text);
if ((dir & View.FOCUS_BACKWARD) != 0) {
text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT);
} else {
text.removeSpan(FROM_BELOW);
}
}
}
@@ -29,21 +29,19 @@ import com.hippo.yorozuya.MathUtils;
import java.io.IOException;
public final class BitmapUtils {
public static Context sContext;
public static ActivityManager activityManager;
private BitmapUtils() {
}
public static void initialize(Context context) {
sContext = context.getApplicationContext();
activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
}
public static long availableMemory() {
final Runtime runtime = Runtime.getRuntime();
final long used = runtime.totalMemory() - runtime.freeMemory();
final ActivityManager activityManager = (ActivityManager) sContext.
getSystemService(Context.ACTIVITY_SERVICE);
final long total = activityManager.getMemoryClass() * 1024 * 1024;
return total - used;
@@ -29,7 +29,7 @@ public class ClipboardUtil {
if (clipboardManager != null) {
try {
clipboardManager.setPrimaryClip(ClipData.newPlainText(null, text));
} catch (Exception e){
} catch (Exception e) {
e.printStackTrace();
}
}
@@ -1,31 +0,0 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import android.content.Context;
import android.graphics.drawable.Drawable;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.core.content.res.ResourcesCompat;
public final class DrawableManager {
public static Drawable getVectorDrawable(@NonNull Context context, @DrawableRes int resId) {
return ResourcesCompat.getDrawable(context.getResources(), resId, context.getTheme());
}
}
@@ -33,8 +33,6 @@ import javax.net.ssl.SSLException;
public final class ExceptionUtils {
private static final String TAG = ExceptionUtils.class.getSimpleName();
@NonNull
public static String getReadableString(@NonNull Throwable e) {
e.printStackTrace();
@@ -38,7 +38,7 @@ public class SqlUtils {
}
public static void dropAllTable(SQLiteDatabase db) {
List<String> tables = new ArrayList<String>();
List<String> tables = new ArrayList<>();
Cursor cursor = db.rawQuery("SELECT * FROM sqlite_master WHERE type='table';", null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
@@ -1,63 +0,0 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.util;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.URLSpan;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class TextUrl {
public static final Charset UTF_8 = StandardCharsets.UTF_8;
private static final Pattern URL_PATTERN = Pattern.compile("(http|https)://[a-z0-9A-Z%-]+(\\.[a-z0-9A-Z%-]+)+(:\\d{1,5})?(/[a-zA-Z0-9-_~:#@!&',;=%/\\*\\.\\?\\+\\$\\[\\]\\(\\)]+)?/?");
public static CharSequence handleTextUrl(CharSequence content) {
Matcher m = URL_PATTERN.matcher(content);
Spannable spannable = null;
while (m.find()) {
// Ensure spannable
if (spannable == null) {
if (content instanceof Spannable) {
spannable = (Spannable) content;
} else {
spannable = new SpannableString(content);
}
}
int start = m.start();
int end = m.end();
URLSpan[] links = spannable.getSpans(start, end, URLSpan.class);
if (links.length > 0) {
// There has been URLSpan already, leave it alone
continue;
}
URLSpan urlSpan = new URLSpan(m.group(0));
spannable.setSpan(urlSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return spannable == null ? content : spannable;
}
}
@@ -31,6 +31,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.hippo.android.resource.AttrResources;
@@ -41,7 +42,6 @@ import com.hippo.easyrecyclerview.LayoutManagerUtils;
import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.R;
import com.hippo.refreshlayout.RefreshLayout;
import com.hippo.util.DrawableManager;
import com.hippo.util.ExceptionUtils;
import com.hippo.view.ViewTransition;
import com.hippo.yorozuya.IntIdGenerator;
@@ -195,13 +195,7 @@ public class ContentLayout extends FrameLayout {
* Generate task id
*/
private final IntIdGenerator mIdGenerator = new IntIdGenerator();
private final LayoutManagerUtils.OnScrollToPositionListener mOnScrollToPositionListener =
new LayoutManagerUtils.OnScrollToPositionListener() {
@Override
public void onScrollToPosition(int position) {
ContentHelper.this.onScrollToPosition(position);
}
};
private final LayoutManagerUtils.OnScrollToPositionListener mOnScrollToPositionListener = ContentHelper.this::onScrollToPosition;
private ProgressView mProgressView;
private TextView mTipView;
private ViewGroup mContentView;
@@ -280,7 +274,7 @@ public class ContentLayout extends FrameLayout {
};
private final RecyclerView.OnScrollListener mOnScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (!mRefreshLayout.isRefreshing() && mRefreshLayout.isAlmostBottom() && mEndPage < mPages) {
// Get next page
mRefreshLayout.setFooterRefreshing(true);
@@ -300,7 +294,7 @@ public class ContentLayout extends FrameLayout {
mRefreshLayout = contentLayout.mRefreshLayout;
mRecyclerView = contentLayout.mRecyclerView;
Drawable drawable = DrawableManager.getVectorDrawable(getContext(), R.drawable.big_sad_pandroid);
Drawable drawable = ContextCompat.getDrawable(getContext(), R.drawable.big_sad_pandroid);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
mTipView.setCompoundDrawables(null, drawable, null, null);
@@ -1,86 +0,0 @@
/*
* Copyright 2018 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.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.TextView;
import com.google.android.material.textfield.TextInputEditText;
import com.hippo.util.ExceptionUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
// Avoid crash on some Meizu devices
// https://github.com/android-in-china/Compatibility/issues/11
// https://stackoverflow.com/questions/51891415/nullpointerexception-on-meizu-devices-in-editor-updatecursorpositionmz/52001305
public class HackyTextInputEditText extends TextInputEditText {
private static final boolean HAS_METHOD_UPDATE_CURSOR_POSITION_MZ;
private static final Field FIELD_M_HINT;
static {
boolean hasMethodUpdateCursorPositionMz = false;
try {
Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass("android.widget.Editor");
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if ("updateCursorPositionMz".equals(method.getName())) {
hasMethodUpdateCursorPositionMz = true;
}
}
} catch (Throwable e) {
ExceptionUtils.throwIfFatal(e);
}
Field fieldMHint = null;
if (hasMethodUpdateCursorPositionMz) {
try {
fieldMHint = TextView.class.getDeclaredField("mHint");
fieldMHint.setAccessible(true);
} catch (Throwable e) {
ExceptionUtils.throwIfFatal(e);
}
}
HAS_METHOD_UPDATE_CURSOR_POSITION_MZ = hasMethodUpdateCursorPositionMz;
FIELD_M_HINT = fieldMHint;
}
public HackyTextInputEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public CharSequence getHint() {
if (HAS_METHOD_UPDATE_CURSOR_POSITION_MZ && FIELD_M_HINT != null) {
try {
return getSuperHint();
} catch (Throwable e) {
ExceptionUtils.throwIfFatal(e);
return super.getHint();
}
} else {
return super.getHint();
}
}
private CharSequence getSuperHint() throws IllegalAccessException {
return (CharSequence) FIELD_M_HINT.get(this);
}
}
@@ -16,6 +16,7 @@
package com.hippo.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.text.Layout;
import android.text.Spanned;
@@ -49,6 +50,7 @@ public class LinkifyTextView extends ObservedTextView {
mCurrentSpan = null;
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
// Let the parent or grandparent of TextView to handles click aciton.
@@ -30,6 +30,7 @@ import android.view.View;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import com.hippo.conaco.Conaco;
import com.hippo.conaco.ConacoTask;
@@ -41,7 +42,6 @@ import com.hippo.ehviewer.R;
import com.hippo.image.ImageBitmap;
import com.hippo.image.ImageDrawable;
import com.hippo.image.RecycledException;
import com.hippo.util.DrawableManager;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -316,7 +316,7 @@ public class LoadImageView extends FixedAspectImageView implements Unikery<Image
public void onFailure() {
mFailed = true;
clearDrawable();
Drawable drawable = DrawableManager.getVectorDrawable(getContext(), R.drawable.image_failed);
Drawable drawable = ContextCompat.getDrawable(getContext(), R.drawable.image_failed);
onPreSetImageDrawable(drawable, true);
setImageDrawable(drawable);
if (mRetryType == RETRY_TYPE_CLICK) {
@@ -1,154 +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.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
public class OffsetLayout extends FrameLayout {
public OffsetLayout(Context context) {
super(context);
}
public OffsetLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public OffsetLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
layoutChildrenEx(left, top, right, bottom, false /* no force left gravity */);
}
// TODO foreground not work fine
@SuppressLint("RtlHardcoded")
void layoutChildrenEx(int left, int top, int right, int bottom,
boolean forceLeftGravity) {
final int count = getChildCount();
final int parentLeft = getPaddingLeft();
final int parentRight = right - left - getPaddingRight();
final int parentTop = getPaddingTop();
final int parentBottom = bottom - top - getPaddingBottom();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int width = child.getMeasuredWidth();
final int height = child.getMeasuredHeight();
int childLeft;
int childTop;
int gravity = lp.gravity;
if (gravity == -1) {
gravity = Gravity.TOP | Gravity.LEFT;
}
final int absoluteGravity = gravity;
final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
case Gravity.CENTER_HORIZONTAL:
childLeft = parentLeft + (parentRight - parentLeft - width) / 2 +
lp.leftMargin - lp.rightMargin;
break;
case Gravity.RIGHT:
if (!forceLeftGravity) {
childLeft = parentRight - width - lp.rightMargin;
break;
}
case Gravity.LEFT:
default:
childLeft = parentLeft + lp.leftMargin;
}
switch (verticalGravity) {
case Gravity.TOP:
childTop = parentTop + lp.topMargin;
break;
case Gravity.CENTER_VERTICAL:
childTop = parentTop + (parentBottom - parentTop - height) / 2 +
lp.topMargin - lp.bottomMargin;
break;
case Gravity.BOTTOM:
childTop = parentBottom - height - lp.bottomMargin;
break;
default:
childTop = parentTop + lp.topMargin;
}
child.layout(childLeft + lp.offsetX, childTop + lp.offsetY,
childLeft + width + lp.offsetX, childTop + height + lp.offsetY);
}
}
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return new LayoutParams(p);
}
public static class LayoutParams extends FrameLayout.LayoutParams {
public int offsetX;
public int offsetY;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
}
public LayoutParams(MarginLayoutParams source) {
super(source);
}
public LayoutParams(FrameLayout.LayoutParams source) {
super((ViewGroup.MarginLayoutParams) source);
this.gravity = source.gravity;
}
public LayoutParams(int width, int height) {
super(width, height);
}
}
}
@@ -31,6 +31,7 @@ import android.view.animation.Animation;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.core.view.animation.PathInterpolatorCompat;
@@ -163,45 +164,45 @@ public class ProgressView extends View {
return false;
}
@SuppressWarnings("unused")
@Keep
public float getTrimStart() {
return mTrimStart;
}
@SuppressWarnings("unused")
@Keep
public void setTrimStart(float trimStart) {
mTrimStart = trimStart;
invalidate();
}
@SuppressWarnings("unused")
@Keep
public float getTrimEnd() {
return mTrimEnd;
}
@SuppressWarnings("unused")
@Keep
public void setTrimEnd(float trimEnd) {
mTrimEnd = trimEnd;
invalidate();
}
@SuppressWarnings("unused")
@Keep
public float getTrimOffset() {
return mTrimOffset;
}
@SuppressWarnings("unused")
@Keep
public void setTrimOffset(float trimOffset) {
mTrimOffset = trimOffset;
invalidate();
}
@SuppressWarnings("unused")
@Keep
public float getTrimRotation() {
return mTrimRotation;
}
@SuppressWarnings("unused")
@Keep
public void setTrimRotation(float trimRotation) {
mTrimRotation = trimRotation;
invalidate();
@@ -144,7 +144,7 @@ public class RadioGridGroup extends SimpleGridLayout {
private void setCheckedStateForView(int viewId, boolean checked) {
View checkedView = findViewById(viewId);
if (checkedView != null && checkedView instanceof RadioButton) {
if (checkedView instanceof RadioButton) {
((RadioButton) checkedView).setChecked(checked);
}
}
@@ -16,6 +16,7 @@
package com.hippo.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
@@ -48,6 +49,7 @@ public class SafeCoordinatorLayout extends CoordinatorLayout {
}
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent ev) {
try {
@@ -20,6 +20,7 @@ import android.animation.Animator;
import android.animation.ValueAnimator;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
@@ -50,14 +51,14 @@ public class SearchBarMover extends RecyclerView.OnScrollListener {
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_IDLE && mHelper.isValidView(recyclerView)) {
returnSearchBarPosition();
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (mHelper.isValidView(recyclerView)) {
int oldBottom = (int) ViewUtils.getY2(mSearchBar);
int offsetYStep = MathUtils.clamp(-dy, -oldBottom, -(int) mSearchBar.getTranslationY());
@@ -1,81 +0,0 @@
/*
* Copyright 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.widget;
import android.content.Context;
import android.util.AttributeSet;
import androidx.appcompat.widget.AppCompatCheckBox;
public class SensitiveCheckBox extends AppCompatCheckBox {
private boolean mFromUser;
private OnCheckedChangeListener mOnCheckedChangeListener;
public SensitiveCheckBox(Context context) {
super(context);
}
public SensitiveCheckBox(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SensitiveCheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean performClick() {
boolean result;
mFromUser = true;
result = super.performClick();
mFromUser = false;
return result;
}
public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
mOnCheckedChangeListener = listener;
}
@Override
public void setChecked(boolean checked) {
super.setChecked(checked);
if (mOnCheckedChangeListener != null) {
mOnCheckedChangeListener.onCheckedChanged(this, checked, mFromUser);
}
}
/**
* Interface definition for a callback to be invoked when the checked state
* of a compound button changed.
*/
public interface OnCheckedChangeListener {
/**
* Called when the checked state of a compound button has changed.
*
* @param view The sensitive check box view whose state has changed.
* @param isChecked The new checked state of buttonView.
* @param fromUser True if the rating change was initiated by a user's
* touch gesture.
*/
void onCheckedChanged(SensitiveCheckBox view, boolean isChecked, boolean fromUser);
}
}
@@ -1,48 +0,0 @@
/*
* Copyright 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.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewOutlineProvider;
import android.widget.LinearLayout;
import com.hippo.yorozuya.LayoutUtils;
public class ShadowLinearLayout extends LinearLayout {
public ShadowLinearLayout(Context context) {
super(context);
init(context);
}
public ShadowLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ShadowLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
setOutlineProvider(ViewOutlineProvider.BOUNDS);
setElevation(LayoutUtils.dp2pix(context, 2));
}
}
@@ -66,6 +66,7 @@
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?attr/gallerySliderBackgroundColor"
android:fitsSystemWindows="true"
android:orientation="horizontal"
android:paddingLeft="16dp"
android:paddingRight="16dp"
@@ -37,7 +37,7 @@
android:layout_marginTop="16dp"
android:hint="@string/filter_text">
<com.hippo.widget.HackyTextInputEditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -22,7 +22,7 @@
android:paddingTop="@dimen/abc_dialog_padding_top_material"
android:paddingRight="?attr/dialogPreferredPadding">
<com.hippo.widget.HackyTextInputEditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+2 -2
View File
@@ -29,7 +29,7 @@
android:layout_height="wrap_content"
android:hint="@string/hosts_host">
<com.hippo.widget.HackyTextInputEditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/host"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -44,7 +44,7 @@
android:layout_height="wrap_content"
android:hint="@string/hosts_ip">
<com.hippo.widget.HackyTextInputEditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/ip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -37,7 +37,7 @@
android:layout_height="wrap_content"
android:hint="@string/proxy_host_or_ip">
<com.hippo.widget.HackyTextInputEditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/ip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -52,7 +52,7 @@
android:layout_height="wrap_content"
android:hint="@string/proxy_port">
<com.hippo.widget.HackyTextInputEditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/port"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -59,7 +59,7 @@
android:hint="ipb_member_id"
android:minWidth="@dimen/single_max_width">
<com.hippo.widget.HackyTextInputEditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/ipb_member_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -80,7 +80,7 @@
android:hint="ipb_pass_hash"
android:minWidth="@dimen/single_max_width">
<com.hippo.widget.HackyTextInputEditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/ipb_pass_hash"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -101,7 +101,7 @@
android:hint="igneous"
android:minWidth="@dimen/single_max_width">
<com.hippo.widget.HackyTextInputEditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/igneous"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+2 -2
View File
@@ -48,7 +48,7 @@
android:hint="@string/username"
android:minWidth="@dimen/single_max_width">
<com.hippo.widget.HackyTextInputEditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -69,7 +69,7 @@
android:minWidth="@dimen/single_max_width"
app:passwordToggleEnabled="true">
<com.hippo.widget.HackyTextInputEditText
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"