Refactor Search
This commit is contained in:
1 parent
747c19c028
commit
8e1bacbfac
5 files changed
+297
-843
No files matched your search
@@ -1,163 +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.ehviewer.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TableLayout;
|
||||
|
||||
import com.hippo.ehviewer.R;
|
||||
import com.hippo.ehviewer.client.EhConfig;
|
||||
import com.hippo.widget.CheckTextView;
|
||||
import com.hippo.yorozuya.NumberUtils;
|
||||
|
||||
public class CategoryTable extends TableLayout implements View.OnLongClickListener {
|
||||
|
||||
private static final String STATE_KEY_SUPER = "super";
|
||||
private static final String STATE_KEY_CATEGORY = "category";
|
||||
|
||||
private CheckTextView mDoujinshi;
|
||||
private CheckTextView mManga;
|
||||
private CheckTextView mArtistCG;
|
||||
private CheckTextView mGameCG;
|
||||
private CheckTextView mWestern;
|
||||
private CheckTextView mNonH;
|
||||
private CheckTextView mImageSets;
|
||||
private CheckTextView mCosplay;
|
||||
private CheckTextView mAsianPorn;
|
||||
private CheckTextView mMisc;
|
||||
|
||||
private CheckTextView[] mOptions;
|
||||
|
||||
public CategoryTable(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public CategoryTable(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
||||
inflater.inflate(R.layout.widget_category_table, this);
|
||||
|
||||
ViewGroup row0 = (ViewGroup) getChildAt(0);
|
||||
mDoujinshi = (CheckTextView) row0.getChildAt(0);
|
||||
mManga = (CheckTextView) row0.getChildAt(1);
|
||||
|
||||
ViewGroup row1 = (ViewGroup) getChildAt(1);
|
||||
mArtistCG = (CheckTextView) row1.getChildAt(0);
|
||||
mGameCG = (CheckTextView) row1.getChildAt(1);
|
||||
|
||||
ViewGroup row2 = (ViewGroup) getChildAt(2);
|
||||
mWestern = (CheckTextView) row2.getChildAt(0);
|
||||
mNonH = (CheckTextView) row2.getChildAt(1);
|
||||
|
||||
ViewGroup row3 = (ViewGroup) getChildAt(3);
|
||||
mImageSets = (CheckTextView) row3.getChildAt(0);
|
||||
mCosplay = (CheckTextView) row3.getChildAt(1);
|
||||
|
||||
ViewGroup row4 = (ViewGroup) getChildAt(4);
|
||||
mAsianPorn = (CheckTextView) row4.getChildAt(0);
|
||||
mMisc = (CheckTextView) row4.getChildAt(1);
|
||||
|
||||
mOptions = new CheckTextView[]{
|
||||
mDoujinshi, mManga, mArtistCG, mGameCG, mWestern,
|
||||
mNonH, mImageSets, mCosplay, mAsianPorn, mMisc
|
||||
};
|
||||
|
||||
for (CheckTextView option : mOptions) {
|
||||
option.setOnLongClickListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
if (v instanceof CheckTextView) {
|
||||
boolean checked = ((CheckTextView) v).isChecked();
|
||||
for (CheckTextView option : mOptions) {
|
||||
if (option != v) {
|
||||
option.setChecked(!checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get category according to button.
|
||||
*
|
||||
* @return the category of this view
|
||||
*/
|
||||
public int getCategory() {
|
||||
int category = 0;
|
||||
if (!mDoujinshi.isChecked()) category |= EhConfig.DOUJINSHI;
|
||||
if (!mManga.isChecked()) category |= EhConfig.MANGA;
|
||||
if (!mArtistCG.isChecked()) category |= EhConfig.ARTIST_CG;
|
||||
if (!mGameCG.isChecked()) category |= EhConfig.GAME_CG;
|
||||
if (!mWestern.isChecked()) category |= EhConfig.WESTERN;
|
||||
if (!mNonH.isChecked()) category |= EhConfig.NON_H;
|
||||
if (!mImageSets.isChecked()) category |= EhConfig.IMAGE_SET;
|
||||
if (!mCosplay.isChecked()) category |= EhConfig.COSPLAY;
|
||||
if (!mAsianPorn.isChecked()) category |= EhConfig.ASIAN_PORN;
|
||||
if (!mMisc.isChecked()) category |= EhConfig.MISC;
|
||||
return category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set each button checked or not according to category.
|
||||
*
|
||||
* @param category target category
|
||||
*/
|
||||
public void setCategory(int category) {
|
||||
mDoujinshi.setChecked(!NumberUtils.int2boolean(category & EhConfig.DOUJINSHI));
|
||||
mManga.setChecked(!NumberUtils.int2boolean(category & EhConfig.MANGA));
|
||||
mArtistCG.setChecked(!NumberUtils.int2boolean(category & EhConfig.ARTIST_CG));
|
||||
mGameCG.setChecked(!NumberUtils.int2boolean(category & EhConfig.GAME_CG));
|
||||
mWestern.setChecked(!NumberUtils.int2boolean(category & EhConfig.WESTERN));
|
||||
mNonH.setChecked(!NumberUtils.int2boolean(category & EhConfig.NON_H));
|
||||
mImageSets.setChecked(!NumberUtils.int2boolean(category & EhConfig.IMAGE_SET));
|
||||
mCosplay.setChecked(!NumberUtils.int2boolean(category & EhConfig.COSPLAY));
|
||||
mAsianPorn.setChecked(!NumberUtils.int2boolean(category & EhConfig.ASIAN_PORN));
|
||||
mMisc.setChecked(!NumberUtils.int2boolean(category & EhConfig.MISC));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parcelable onSaveInstanceState() {
|
||||
final Bundle state = new Bundle();
|
||||
state.putParcelable(STATE_KEY_SUPER, super.onSaveInstanceState());
|
||||
state.putInt(STATE_KEY_CATEGORY, getCategory());
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(Parcelable state) {
|
||||
if (state instanceof Bundle) {
|
||||
final Bundle savedState = (Bundle) state;
|
||||
super.onRestoreInstanceState(savedState.getParcelable(STATE_KEY_SUPER));
|
||||
setCategory(savedState.getInt(STATE_KEY_CATEGORY));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Hippo Seven
|
||||
* Copyright (C) 2022 tarsin norbin
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,391 +13,393 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.hippo.ehviewer.widget
|
||||
|
||||
package com.hippo.ehviewer.widget;
|
||||
import com.hippo.easyrecyclerview.EasyRecyclerView
|
||||
import com.google.android.material.tabs.TabLayout.OnTabSelectedListener
|
||||
import android.view.LayoutInflater
|
||||
import com.google.android.material.chip.ChipGroup
|
||||
import com.hippo.widget.RadioGridGroup
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.easyrecyclerview.MarginItemDecoration
|
||||
import android.view.ViewGroup
|
||||
import android.util.SparseArray
|
||||
import android.os.Parcelable
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.*
|
||||
import kotlin.Throws
|
||||
import com.hippo.ehviewer.client.exception.EhException
|
||||
import com.hippo.ehviewer.client.data.ListUrlBuilder
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import androidx.annotation.IntDef
|
||||
import androidx.core.content.edit
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.hippo.easyrecyclerview.SimpleHolder
|
||||
import com.hippo.ehviewer.client.EhConfig
|
||||
import com.hippo.yorozuya.NumberUtils
|
||||
import com.hippo.yorozuya.ViewUtils
|
||||
import java.lang.IndexOutOfBoundsException
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.SparseArray;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
class SearchLayout : EasyRecyclerView, CompoundButton.OnCheckedChangeListener, View.OnClickListener,
|
||||
ImageSearchLayout.Helper, OnTabSelectedListener {
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
private val mInflater : LayoutInflater
|
||||
private val mSharePref : SharedPreferences
|
||||
|
||||
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;
|
||||
import com.hippo.widget.RadioGridGroup;
|
||||
import com.hippo.yorozuya.ViewUtils;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
public class SearchLayout extends EasyRecyclerView implements CompoundButton.OnCheckedChangeListener,
|
||||
View.OnClickListener, ImageSearchLayout.Helper, TabLayout.OnTabSelectedListener {
|
||||
|
||||
public static final int SEARCH_MODE_NORMAL = 0;
|
||||
public static final int SEARCH_MODE_IMAGE = 1;
|
||||
private static final String STATE_KEY_SUPER = "super";
|
||||
private static final String STATE_KEY_SEARCH_MODE = "search_mode";
|
||||
private static final String STATE_KEY_ENABLE_ADVANCE = "enable_advance";
|
||||
private static final int ITEM_TYPE_NORMAL = 0;
|
||||
private static final int ITEM_TYPE_NORMAL_ADVANCE = 1;
|
||||
private static final int ITEM_TYPE_IMAGE = 2;
|
||||
private static final int ITEM_TYPE_ACTION = 3;
|
||||
private static final int[] SEARCH_ITEM_COUNT_ARRAY = {
|
||||
3, 2
|
||||
};
|
||||
private static final int[][] SEARCH_ITEM_TYPE = {
|
||||
{ITEM_TYPE_NORMAL, ITEM_TYPE_NORMAL_ADVANCE, ITEM_TYPE_ACTION}, // SEARCH_MODE_NORMAL
|
||||
{ITEM_TYPE_IMAGE, ITEM_TYPE_ACTION}, // SEARCH_MODE_IMAGE
|
||||
};
|
||||
private LayoutInflater mInflater;
|
||||
@SearchMode
|
||||
private int mSearchMode = SEARCH_MODE_NORMAL;
|
||||
private boolean mEnableAdvance = false;
|
||||
private View mNormalView;
|
||||
private CategoryTable mCategoryTable;
|
||||
private RadioGridGroup mNormalSearchMode;
|
||||
private ImageView mNormalSearchModeHelp;
|
||||
private Switch mEnableAdvanceSwitch;
|
||||
private View mAdvanceView;
|
||||
private AdvanceSearchTable mTableAdvanceSearch;
|
||||
private ImageSearchLayout mImageView;
|
||||
private View mActionView;
|
||||
private TabLayout mAction;
|
||||
private LinearLayoutManager mLayoutManager;
|
||||
private SearchAdapter mAdapter;
|
||||
private Helper mHelper;
|
||||
private var mSearchMode = SEARCH_MODE_NORMAL
|
||||
private var mEnableAdvance = false
|
||||
private var mNormalView: View? = null
|
||||
private var mNormalSearchMode: RadioGridGroup? = null
|
||||
private var mNormalSearchModeHelp: ImageView? = null
|
||||
private var mEnableAdvanceSwitch: Switch? = null
|
||||
private var mAdvanceView: View? = null
|
||||
private var mTableAdvanceSearch: AdvanceSearchTable? = null
|
||||
private var mImageView: ImageSearchLayout? = null
|
||||
private var mActionView: View? = null
|
||||
private var mAction: TabLayout? = null
|
||||
private var mLayoutManager: LinearLayoutManager? = null
|
||||
private var mAdapter: SearchAdapter? = null
|
||||
private var mHelper: Helper? = null
|
||||
|
||||
public SearchLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
private val mCategoryTable : ArrayList<Pair<Int, Int>> = arrayListOf(
|
||||
Pair(EhConfig.DOUJINSHI, R.string.doujinshi),
|
||||
Pair(EhConfig.MANGA, R.string.manga),
|
||||
Pair(EhConfig.ARTIST_CG, R.string.artist_cg),
|
||||
Pair(EhConfig.GAME_CG, R.string.game_cg),
|
||||
Pair(EhConfig.WESTERN, R.string.western),
|
||||
Pair(EhConfig.NON_H, R.string.non_h),
|
||||
Pair(EhConfig.IMAGE_SET, R.string.image_set),
|
||||
Pair(EhConfig.COSPLAY, R.string.cosplay),
|
||||
Pair(EhConfig.ASIAN_PORN, R.string.asian_porn),
|
||||
Pair(EhConfig.MISC, R.string.misc)
|
||||
)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
|
||||
mSharePref = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
mInflater = LayoutInflater.from(context)
|
||||
init(context)
|
||||
}
|
||||
|
||||
public SearchLayout(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init(context);
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyle
|
||||
) {
|
||||
mSharePref = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
mInflater = LayoutInflater.from(context)
|
||||
init(context)
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
private void init(Context context) {
|
||||
Resources resources = context.getResources();
|
||||
mInflater = LayoutInflater.from(context);
|
||||
|
||||
mLayoutManager = new SearchLayoutManager(context);
|
||||
mAdapter = new SearchAdapter();
|
||||
mAdapter.setHasStableIds(true);
|
||||
setLayoutManager(mLayoutManager);
|
||||
setAdapter(mAdapter);
|
||||
setHasFixedSize(true);
|
||||
setClipToPadding(false);
|
||||
((DefaultItemAnimator) getItemAnimator()).setSupportsChangeAnimations(false);
|
||||
int interval = resources.getDimensionPixelOffset(R.dimen.search_layout_interval);
|
||||
int paddingH = resources.getDimensionPixelOffset(R.dimen.search_layout_margin_h);
|
||||
int paddingV = resources.getDimensionPixelOffset(R.dimen.search_layout_margin_v);
|
||||
MarginItemDecoration decoration = new MarginItemDecoration(
|
||||
interval, paddingH, paddingV, paddingH, paddingV);
|
||||
addItemDecoration(decoration);
|
||||
decoration.applyPaddings(this);
|
||||
private fun init(context: Context) {
|
||||
val resources = context.resources
|
||||
mLayoutManager = SearchLayoutManager(context)
|
||||
mAdapter = SearchAdapter()
|
||||
mAdapter!!.setHasStableIds(true)
|
||||
layoutManager = mLayoutManager
|
||||
adapter = mAdapter
|
||||
setHasFixedSize(true)
|
||||
clipToPadding = false
|
||||
(itemAnimator as DefaultItemAnimator?)!!.supportsChangeAnimations = false
|
||||
val interval = resources.getDimensionPixelOffset(R.dimen.search_layout_interval)
|
||||
val paddingH = resources.getDimensionPixelOffset(R.dimen.search_layout_margin_h)
|
||||
val paddingV = resources.getDimensionPixelOffset(R.dimen.search_layout_margin_v)
|
||||
val decoration = MarginItemDecoration(
|
||||
interval, paddingH, paddingV, paddingH, paddingV
|
||||
)
|
||||
addItemDecoration(decoration)
|
||||
decoration.applyPaddings(this)
|
||||
|
||||
// Create normal view
|
||||
View normalView = mInflater.inflate(R.layout.search_normal, null);
|
||||
mNormalView = normalView;
|
||||
mCategoryTable = normalView.findViewById(R.id.search_category_table);
|
||||
mNormalSearchMode = normalView.findViewById(R.id.normal_search_mode);
|
||||
mNormalSearchModeHelp = normalView.findViewById(R.id.normal_search_mode_help);
|
||||
mEnableAdvanceSwitch = normalView.findViewById(R.id.search_enable_advance);
|
||||
mNormalSearchModeHelp.setOnClickListener(this);
|
||||
mEnableAdvanceSwitch.setOnCheckedChangeListener(this);
|
||||
mEnableAdvanceSwitch.setSwitchPadding(resources.getDimensionPixelSize(R.dimen.switch_padding));
|
||||
val normalView = mInflater.inflate(R.layout.search_normal, null)
|
||||
mNormalView = normalView
|
||||
val mCategoryStored = mSharePref.getInt(SEARCH_CATEGORY_PREF, EhConfig.ALL_CATEGORY)
|
||||
|
||||
val mCategoryGroup = normalView.findViewById(R.id.search_category_chipgroup) as ChipGroup
|
||||
for (mPair in mCategoryTable) {
|
||||
val mChip = Chip(context)
|
||||
mChip.isCheckable = true
|
||||
mChip.setText(mPair.second)
|
||||
mChip.isChecked = NumberUtils.int2boolean(mPair.first and mCategoryStored)
|
||||
mCategoryGroup.addView(mChip)
|
||||
}
|
||||
mCategoryGroup.setOnCheckedStateChangeListener { group, checkedIds ->
|
||||
var mCategory = 0
|
||||
for (index in checkedIds) {
|
||||
mCategory = mCategory or mCategoryTable[index - 1].first
|
||||
}
|
||||
mSharePref.edit { putInt(SEARCH_CATEGORY_PREF, mCategory) }
|
||||
}
|
||||
|
||||
mNormalSearchMode = normalView.findViewById(R.id.normal_search_mode)
|
||||
mNormalSearchModeHelp = normalView.findViewById(R.id.normal_search_mode_help)
|
||||
mEnableAdvanceSwitch = normalView.findViewById(R.id.search_enable_advance)
|
||||
mNormalSearchModeHelp!!.setOnClickListener(this)
|
||||
mEnableAdvanceSwitch!!.setOnCheckedChangeListener(this)
|
||||
mEnableAdvanceSwitch!!.switchPadding = resources.getDimensionPixelSize(R.dimen.switch_padding)
|
||||
|
||||
// Create advance view
|
||||
mAdvanceView = mInflater.inflate(R.layout.search_advance, null);
|
||||
mTableAdvanceSearch = mAdvanceView.findViewById(R.id.search_advance_search_table);
|
||||
mAdvanceView = mInflater.inflate(R.layout.search_advance, null)
|
||||
mTableAdvanceSearch = mAdvanceView!!.findViewById(R.id.search_advance_search_table)
|
||||
|
||||
// Create image view
|
||||
mImageView = (ImageSearchLayout) mInflater.inflate(R.layout.search_image, null);
|
||||
mImageView.setHelper(this);
|
||||
mImageView = mInflater.inflate(R.layout.search_image, null) as ImageSearchLayout
|
||||
mImageView!!.setHelper(this)
|
||||
|
||||
// Create action view
|
||||
mActionView = mInflater.inflate(R.layout.search_action, null);
|
||||
mActionView.setLayoutParams(new RecyclerView.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
mAction = mActionView.findViewById(R.id.action);
|
||||
mAction.addOnTabSelectedListener(this);
|
||||
mActionView = mInflater.inflate(R.layout.search_action, null)
|
||||
mActionView!!.layoutParams = LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
mAction = mActionView!!.findViewById(R.id.action)
|
||||
mAction!!.addOnTabSelectedListener(this)
|
||||
}
|
||||
|
||||
public void setHelper(Helper helper) {
|
||||
mHelper = helper;
|
||||
fun setHelper(helper: Helper?) {
|
||||
mHelper = helper
|
||||
}
|
||||
|
||||
public void scrollSearchContainerToTop() {
|
||||
mLayoutManager.scrollToPositionWithOffset(0, 0);
|
||||
fun scrollSearchContainerToTop() {
|
||||
mLayoutManager!!.scrollToPositionWithOffset(0, 0)
|
||||
}
|
||||
|
||||
public void setImageUri(Uri imageUri) {
|
||||
mImageView.setImageUri(imageUri);
|
||||
fun setImageUri(imageUri: Uri?) {
|
||||
mImageView!!.setImageUri(imageUri)
|
||||
}
|
||||
|
||||
public void setNormalSearchMode(int id) {
|
||||
mNormalSearchMode.check(id);
|
||||
fun setNormalSearchMode(id: Int) {
|
||||
mNormalSearchMode!!.check(id)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelectImage() {
|
||||
override fun onSelectImage() {
|
||||
if (mHelper != null) {
|
||||
mHelper.onSelectImage();
|
||||
mHelper!!.onSelectImage()
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchSaveInstanceState(@NonNull SparseArray<Parcelable> container) {
|
||||
super.dispatchSaveInstanceState(container);
|
||||
|
||||
mNormalView.saveHierarchyState(container);
|
||||
mAdvanceView.saveHierarchyState(container);
|
||||
mImageView.saveHierarchyState(container);
|
||||
mActionView.saveHierarchyState(container);
|
||||
override fun dispatchSaveInstanceState(container: SparseArray<Parcelable>) {
|
||||
super.dispatchSaveInstanceState(container)
|
||||
mNormalView!!.saveHierarchyState(container)
|
||||
mAdvanceView!!.saveHierarchyState(container)
|
||||
mImageView!!.saveHierarchyState(container)
|
||||
mActionView!!.saveHierarchyState(container)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchRestoreInstanceState(@NonNull SparseArray<Parcelable> container) {
|
||||
super.dispatchRestoreInstanceState(container);
|
||||
|
||||
mNormalView.restoreHierarchyState(container);
|
||||
mAdvanceView.restoreHierarchyState(container);
|
||||
mImageView.restoreHierarchyState(container);
|
||||
mActionView.restoreHierarchyState(container);
|
||||
override fun dispatchRestoreInstanceState(container: SparseArray<Parcelable>) {
|
||||
super.dispatchRestoreInstanceState(container)
|
||||
mNormalView!!.restoreHierarchyState(container)
|
||||
mAdvanceView!!.restoreHierarchyState(container)
|
||||
mImageView!!.restoreHierarchyState(container)
|
||||
mActionView!!.restoreHierarchyState(container)
|
||||
}
|
||||
|
||||
@Override
|
||||
public Parcelable onSaveInstanceState() {
|
||||
final Bundle state = new Bundle();
|
||||
state.putParcelable(STATE_KEY_SUPER, super.onSaveInstanceState());
|
||||
state.putInt(STATE_KEY_SEARCH_MODE, mSearchMode);
|
||||
state.putBoolean(STATE_KEY_ENABLE_ADVANCE, mEnableAdvance);
|
||||
return state;
|
||||
override fun onSaveInstanceState(): Parcelable {
|
||||
val state = Bundle()
|
||||
state.putParcelable(STATE_KEY_SUPER, super.onSaveInstanceState())
|
||||
state.putInt(STATE_KEY_SEARCH_MODE, mSearchMode)
|
||||
state.putBoolean(STATE_KEY_ENABLE_ADVANCE, mEnableAdvance)
|
||||
return state
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestoreInstanceState(Parcelable state) {
|
||||
if (state instanceof Bundle) {
|
||||
final Bundle savedState = (Bundle) state;
|
||||
super.onRestoreInstanceState(savedState.getParcelable(STATE_KEY_SUPER));
|
||||
mSearchMode = savedState.getInt(STATE_KEY_SEARCH_MODE);
|
||||
mEnableAdvance = savedState.getBoolean(STATE_KEY_ENABLE_ADVANCE);
|
||||
override fun onRestoreInstanceState(state: Parcelable) {
|
||||
if (state is Bundle) {
|
||||
super.onRestoreInstanceState(state.getParcelable(STATE_KEY_SUPER))
|
||||
mSearchMode = state.getInt(STATE_KEY_SEARCH_MODE)
|
||||
mEnableAdvance = state.getBoolean(STATE_KEY_ENABLE_ADVANCE)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
if (buttonView == mEnableAdvanceSwitch) {
|
||||
post(() -> {
|
||||
mEnableAdvance = isChecked;
|
||||
override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) {
|
||||
if (buttonView === mEnableAdvanceSwitch) {
|
||||
post {
|
||||
mEnableAdvance = isChecked
|
||||
if (mSearchMode == SEARCH_MODE_NORMAL) {
|
||||
if (mEnableAdvance) {
|
||||
mAdapter.notifyItemInserted(1);
|
||||
mAdapter!!.notifyItemInserted(1)
|
||||
} else {
|
||||
mAdapter.notifyItemRemoved(1);
|
||||
mAdapter!!.notifyItemRemoved(1)
|
||||
}
|
||||
|
||||
if (mHelper != null) {
|
||||
mHelper.onChangeSearchMode();
|
||||
mHelper!!.onChangeSearchMode()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NonConstantResourceId")
|
||||
public void formatListUrlBuilder(ListUrlBuilder urlBuilder, String query) throws EhException {
|
||||
urlBuilder.reset();
|
||||
|
||||
switch (mSearchMode) {
|
||||
case SEARCH_MODE_NORMAL:
|
||||
int nsMode = mNormalSearchMode.getCheckedRadioButtonId();
|
||||
if (nsMode == R.id.search_subscription_search) {
|
||||
urlBuilder.setMode(ListUrlBuilder.MODE_SUBSCRIPTION);
|
||||
} else if (nsMode == R.id.search_specify_uploader) {
|
||||
urlBuilder.setMode(ListUrlBuilder.MODE_UPLOADER);
|
||||
} else if (nsMode == R.id.search_specify_tag) {
|
||||
urlBuilder.setMode(ListUrlBuilder.MODE_TAG);
|
||||
} else {
|
||||
urlBuilder.setMode(ListUrlBuilder.MODE_NORMAL);
|
||||
@Throws(EhException::class)
|
||||
fun formatListUrlBuilder(urlBuilder: ListUrlBuilder, query: String?) {
|
||||
urlBuilder.reset()
|
||||
when (mSearchMode) {
|
||||
SEARCH_MODE_NORMAL -> {
|
||||
when (mNormalSearchMode!!.checkedRadioButtonId) {
|
||||
R.id.search_subscription_search -> {
|
||||
urlBuilder.mode = ListUrlBuilder.MODE_SUBSCRIPTION
|
||||
}
|
||||
R.id.search_specify_uploader -> {
|
||||
urlBuilder.mode = ListUrlBuilder.MODE_UPLOADER
|
||||
}
|
||||
R.id.search_specify_tag -> {
|
||||
urlBuilder.mode = ListUrlBuilder.MODE_TAG
|
||||
}
|
||||
else -> {
|
||||
urlBuilder.mode = ListUrlBuilder.MODE_NORMAL
|
||||
}
|
||||
}
|
||||
urlBuilder.setKeyword(query);
|
||||
urlBuilder.setCategory(mCategoryTable.getCategory());
|
||||
urlBuilder.keyword = query
|
||||
urlBuilder.category = PreferenceManager.getDefaultSharedPreferences(context).getInt(
|
||||
SEARCH_CATEGORY_PREF, 0)
|
||||
if (mEnableAdvance) {
|
||||
urlBuilder.setAdvanceSearch(mTableAdvanceSearch.getAdvanceSearch());
|
||||
urlBuilder.setMinRating(mTableAdvanceSearch.getMinRating());
|
||||
urlBuilder.setPageFrom(mTableAdvanceSearch.getPageFrom());
|
||||
urlBuilder.setPageTo(mTableAdvanceSearch.getPageTo());
|
||||
urlBuilder.advanceSearch = mTableAdvanceSearch!!.advanceSearch
|
||||
urlBuilder.minRating = mTableAdvanceSearch!!.minRating
|
||||
urlBuilder.pageFrom = mTableAdvanceSearch!!.pageFrom
|
||||
urlBuilder.pageTo = mTableAdvanceSearch!!.pageTo
|
||||
}
|
||||
break;
|
||||
case SEARCH_MODE_IMAGE:
|
||||
urlBuilder.setMode(ListUrlBuilder.MODE_IMAGE_SEARCH);
|
||||
mImageView.formatListUrlBuilder(urlBuilder);
|
||||
break;
|
||||
}
|
||||
SEARCH_MODE_IMAGE -> {
|
||||
urlBuilder.mode = ListUrlBuilder.MODE_IMAGE_SEARCH
|
||||
mImageView!!.formatListUrlBuilder(urlBuilder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mNormalSearchModeHelp == v) {
|
||||
new MaterialAlertDialogBuilder(getContext())
|
||||
.setMessage(R.string.search_tip)
|
||||
.show();
|
||||
override fun onClick(v: View) {
|
||||
if (mNormalSearchModeHelp === v) {
|
||||
MaterialAlertDialogBuilder(context)
|
||||
.setMessage(R.string.search_tip)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
post(() -> setSearchMode(tab.getPosition()));
|
||||
override fun onTabSelected(tab: TabLayout.Tab) {
|
||||
post { setSearchMode(tab.position) }
|
||||
}
|
||||
|
||||
public void setSearchMode(@SearchMode int mode) {
|
||||
int oldItemCount = mAdapter.getItemCount();
|
||||
|
||||
mSearchMode = mode;
|
||||
|
||||
int newItemCount = mAdapter.getItemCount();
|
||||
|
||||
mAdapter.notifyItemRangeRemoved(0, oldItemCount - 1);
|
||||
mAdapter.notifyItemRangeInserted(0, newItemCount - 1);
|
||||
|
||||
fun setSearchMode(@SearchMode mode: Int) {
|
||||
val oldItemCount = mAdapter!!.itemCount
|
||||
mSearchMode = mode
|
||||
val newItemCount = mAdapter!!.itemCount
|
||||
mAdapter!!.notifyItemRangeRemoved(0, oldItemCount - 1)
|
||||
mAdapter!!.notifyItemRangeInserted(0, newItemCount - 1)
|
||||
if (mHelper != null) {
|
||||
mHelper.onChangeSearchMode();
|
||||
mHelper!!.onChangeSearchMode()
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabUnselected(TabLayout.Tab tab) {
|
||||
override fun onTabUnselected(tab: TabLayout.Tab) {}
|
||||
override fun onTabReselected(tab: TabLayout.Tab) {}
|
||||
|
||||
@IntDef(SEARCH_MODE_NORMAL, SEARCH_MODE_IMAGE)
|
||||
@kotlin.annotation.Retention(AnnotationRetention.SOURCE)
|
||||
private annotation class SearchMode
|
||||
interface Helper {
|
||||
fun onChangeSearchMode()
|
||||
fun onSelectImage()
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabReselected(TabLayout.Tab tab) {
|
||||
|
||||
}
|
||||
|
||||
@IntDef({SEARCH_MODE_NORMAL, SEARCH_MODE_IMAGE})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
private @interface SearchMode {
|
||||
}
|
||||
|
||||
public interface Helper {
|
||||
void onChangeSearchMode();
|
||||
|
||||
void onSelectImage();
|
||||
}
|
||||
|
||||
static class SearchLayoutManager extends LinearLayoutManager {
|
||||
|
||||
public SearchLayoutManager(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
|
||||
internal class SearchLayoutManager(context: Context?) : LinearLayoutManager(context) {
|
||||
override fun onLayoutChildren(recycler: Recycler, state: State) {
|
||||
try {
|
||||
super.onLayoutChildren(recycler, state);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
e.printStackTrace();
|
||||
super.onLayoutChildren(recycler, state)
|
||||
} catch (e: IndexOutOfBoundsException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SearchAdapter extends EasyRecyclerView.Adapter<SimpleHolder> {
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
int count = SEARCH_ITEM_COUNT_ARRAY[mSearchMode];
|
||||
private inner class SearchAdapter : Adapter<SimpleHolder>() {
|
||||
override fun getItemCount(): Int {
|
||||
var count = SEARCH_ITEM_COUNT_ARRAY[mSearchMode]
|
||||
if (mSearchMode == SEARCH_MODE_NORMAL && !mEnableAdvance) {
|
||||
count--;
|
||||
count--
|
||||
}
|
||||
return count;
|
||||
return count
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
int type = SEARCH_ITEM_TYPE[mSearchMode][position];
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
var type = SEARCH_ITEM_TYPE[mSearchMode][position]
|
||||
if (mSearchMode == SEARCH_MODE_NORMAL && position == 1 && !mEnableAdvance) {
|
||||
type = ITEM_TYPE_ACTION;
|
||||
type = ITEM_TYPE_ACTION
|
||||
}
|
||||
return type;
|
||||
return type
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SimpleHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view;
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SimpleHolder {
|
||||
val view: View?
|
||||
if (viewType == ITEM_TYPE_ACTION) {
|
||||
ViewUtils.removeFromParent(mActionView);
|
||||
view = mActionView;
|
||||
ViewUtils.removeFromParent(mActionView)
|
||||
view = mActionView
|
||||
} else {
|
||||
view = mInflater.inflate(R.layout.search_category, parent, false);
|
||||
TextView title = view.findViewById(R.id.category_title);
|
||||
FrameLayout content = view.findViewById(R.id.category_content);
|
||||
switch (viewType) {
|
||||
case ITEM_TYPE_NORMAL:
|
||||
title.setText(R.string.search_normal);
|
||||
ViewUtils.removeFromParent(mNormalView);
|
||||
content.addView(mNormalView);
|
||||
break;
|
||||
case ITEM_TYPE_NORMAL_ADVANCE:
|
||||
title.setText(R.string.search_advance);
|
||||
ViewUtils.removeFromParent(mAdvanceView);
|
||||
content.addView(mAdvanceView);
|
||||
break;
|
||||
case ITEM_TYPE_IMAGE:
|
||||
title.setText(R.string.search_image);
|
||||
ViewUtils.removeFromParent(mImageView);
|
||||
content.addView(mImageView);
|
||||
break;
|
||||
view = mInflater.inflate(R.layout.search_category, parent, false)
|
||||
val title = view.findViewById<TextView>(R.id.category_title)
|
||||
val content = view.findViewById<FrameLayout>(R.id.category_content)
|
||||
when (viewType) {
|
||||
ITEM_TYPE_NORMAL -> {
|
||||
title.setText(R.string.search_normal)
|
||||
ViewUtils.removeFromParent(mNormalView)
|
||||
content.addView(mNormalView)
|
||||
}
|
||||
ITEM_TYPE_NORMAL_ADVANCE -> {
|
||||
title.setText(R.string.search_advance)
|
||||
ViewUtils.removeFromParent(mAdvanceView)
|
||||
content.addView(mAdvanceView)
|
||||
}
|
||||
ITEM_TYPE_IMAGE -> {
|
||||
title.setText(R.string.search_image)
|
||||
ViewUtils.removeFromParent(mImageView)
|
||||
content.addView(mImageView)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new SimpleHolder(view);
|
||||
return SimpleHolder(view)
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(SimpleHolder holder, int position) {
|
||||
if (holder.getItemViewType() == ITEM_TYPE_ACTION) {
|
||||
mAction.selectTab(mAction.getTabAt(mSearchMode));
|
||||
override fun onBindViewHolder(holder: SimpleHolder, position: Int) {
|
||||
if (holder.itemViewType == ITEM_TYPE_ACTION) {
|
||||
mAction!!.selectTab(mAction!!.getTabAt(mSearchMode))
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
int type = SEARCH_ITEM_TYPE[mSearchMode][position];
|
||||
override fun getItemId(position: Int): Long {
|
||||
var type = SEARCH_ITEM_TYPE[mSearchMode][position]
|
||||
if (mSearchMode == SEARCH_MODE_NORMAL && position == 1 && !mEnableAdvance) {
|
||||
type = ITEM_TYPE_ACTION;
|
||||
type = ITEM_TYPE_ACTION
|
||||
}
|
||||
return type;
|
||||
return type.toLong()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val SEARCH_MODE_NORMAL = 0
|
||||
const val SEARCH_MODE_IMAGE = 1
|
||||
private const val STATE_KEY_SUPER = "super"
|
||||
private const val STATE_KEY_SEARCH_MODE = "search_mode"
|
||||
private const val STATE_KEY_ENABLE_ADVANCE = "enable_advance"
|
||||
const val SEARCH_CATEGORY_PREF = "search_pref"
|
||||
private const val ITEM_TYPE_NORMAL = 0
|
||||
private const val ITEM_TYPE_NORMAL_ADVANCE = 1
|
||||
private const val ITEM_TYPE_IMAGE = 2
|
||||
private const val ITEM_TYPE_ACTION = 3
|
||||
private val SEARCH_ITEM_COUNT_ARRAY = intArrayOf(
|
||||
3, 2
|
||||
)
|
||||
private val SEARCH_ITEM_TYPE = arrayOf(
|
||||
intArrayOf(ITEM_TYPE_NORMAL, ITEM_TYPE_NORMAL_ADVANCE, ITEM_TYPE_ACTION), intArrayOf(
|
||||
ITEM_TYPE_IMAGE, ITEM_TYPE_ACTION
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,236 +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.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.AppCompatCheckedTextView;
|
||||
|
||||
import com.hippo.ehviewer.R;
|
||||
|
||||
public class CheckTextView extends AppCompatCheckedTextView implements View.OnClickListener {
|
||||
|
||||
private final Rect mSelfBounds = new Rect();
|
||||
private final Rect mOverlayBounds = new Rect();
|
||||
protected boolean mForegroundInPadding = true;
|
||||
boolean mForegroundBoundsChanged = false;
|
||||
private Drawable mForeground;
|
||||
private int mForegroundGravity = Gravity.FILL;
|
||||
|
||||
public CheckTextView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public CheckTextView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public CheckTextView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
init(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CheckTextView,
|
||||
defStyleAttr, 0);
|
||||
|
||||
mForegroundGravity = a.getInt(
|
||||
R.styleable.CheckTextView_android_foregroundGravity, mForegroundGravity);
|
||||
|
||||
Drawable d = a.getDrawable(R.styleable.CheckTextView_android_foreground);
|
||||
if (d != null) {
|
||||
setForeground(d);
|
||||
}
|
||||
|
||||
mForegroundInPadding = a.getBoolean(
|
||||
R.styleable.CheckTextView_foregroundInsidePadding, true);
|
||||
|
||||
a.recycle();
|
||||
setOnClickListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes how the foreground is positioned.
|
||||
*
|
||||
* @return foreground gravity.
|
||||
* @see #setForegroundGravity(int)
|
||||
*/
|
||||
public int getForegroundGravity() {
|
||||
return mForegroundGravity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes how the foreground is positioned. Defaults to START and TOP.
|
||||
*
|
||||
* @param foregroundGravity See {@link android.view.Gravity}
|
||||
* @see #getForegroundGravity()
|
||||
*/
|
||||
public void setForegroundGravity(int foregroundGravity) {
|
||||
if (mForegroundGravity != foregroundGravity) {
|
||||
if ((foregroundGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK) == 0) {
|
||||
foregroundGravity |= Gravity.START;
|
||||
}
|
||||
|
||||
if ((foregroundGravity & Gravity.VERTICAL_GRAVITY_MASK) == 0) {
|
||||
foregroundGravity |= Gravity.TOP;
|
||||
}
|
||||
|
||||
mForegroundGravity = foregroundGravity;
|
||||
|
||||
if (mForegroundGravity == Gravity.FILL && mForeground != null) {
|
||||
Rect padding = new Rect();
|
||||
mForeground.getPadding(padding);
|
||||
}
|
||||
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean verifyDrawable(@NonNull Drawable who) {
|
||||
return super.verifyDrawable(who) || (who == mForeground);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jumpDrawablesToCurrentState() {
|
||||
super.jumpDrawablesToCurrentState();
|
||||
if (mForeground != null) {
|
||||
mForeground.jumpToCurrentState();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawableStateChanged() {
|
||||
super.drawableStateChanged();
|
||||
if (mForeground != null && mForeground.isStateful()) {
|
||||
mForeground.setState(getDrawableState());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the drawable used as the foreground of this FrameLayout. The
|
||||
* foreground drawable, if non-null, is always drawn on top of the children.
|
||||
*
|
||||
* @return A Drawable or null if no foreground was set.
|
||||
*/
|
||||
public Drawable getForeground() {
|
||||
return mForeground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supply a Drawable that is to be rendered on top of all of the child
|
||||
* views in the frame layout. Any padding in the Drawable will be taken
|
||||
* into account by ensuring that the children are inset to be placed
|
||||
* inside of the padding area.
|
||||
*
|
||||
* @param drawable The Drawable to be drawn on top of the children.
|
||||
*/
|
||||
public void setForeground(Drawable drawable) {
|
||||
if (mForeground != drawable) {
|
||||
if (mForeground != null) {
|
||||
mForeground.setCallback(null);
|
||||
unscheduleDrawable(mForeground);
|
||||
}
|
||||
|
||||
mForeground = drawable;
|
||||
|
||||
if (drawable != null) {
|
||||
setWillNotDraw(false);
|
||||
drawable.setCallback(this);
|
||||
if (drawable.isStateful()) {
|
||||
drawable.setState(getDrawableState());
|
||||
}
|
||||
if (mForegroundGravity == Gravity.FILL) {
|
||||
Rect padding = new Rect();
|
||||
drawable.getPadding(padding);
|
||||
}
|
||||
} else {
|
||||
setWillNotDraw(true);
|
||||
}
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
mForegroundBoundsChanged |= changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
mForegroundBoundsChanged = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
super.draw(canvas);
|
||||
|
||||
if (mForeground != null) {
|
||||
final Drawable foreground = mForeground;
|
||||
|
||||
if (mForegroundBoundsChanged) {
|
||||
mForegroundBoundsChanged = false;
|
||||
final Rect selfBounds = mSelfBounds;
|
||||
final Rect overlayBounds = mOverlayBounds;
|
||||
|
||||
final int w = getRight() - getLeft();
|
||||
final int h = getBottom() - getTop();
|
||||
|
||||
if (mForegroundInPadding) {
|
||||
selfBounds.set(0, 0, w, h);
|
||||
} else {
|
||||
selfBounds.set(getPaddingLeft(), getPaddingTop(),
|
||||
w - getPaddingRight(), h - getPaddingBottom());
|
||||
}
|
||||
|
||||
Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
|
||||
foreground.getIntrinsicHeight(), selfBounds, overlayBounds);
|
||||
foreground.setBounds(overlayBounds);
|
||||
}
|
||||
|
||||
foreground.draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawableHotspotChanged(float x, float y) {
|
||||
super.drawableHotspotChanged(x, y);
|
||||
if (mForeground != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
mForeground.setHotspot(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setChecked(!isChecked());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user