...">

测试

作者: 我是一个Android开发 | 来源:发表于2022-03-18 21:57 被阅读0次

    <declare-styleable name="NiceSpinner">

        <attr name="arrowTint" format="color" />

        <attr name="hideArrow" format="boolean" />

        <attr name="arrowDrawable" format="reference|color" />

        <attr name="dropDownListPaddingBottom" format="dimension" />

        <attr name="backgroundSelector" format="integer" />

        <attr name="textTint" format="color" />

        <attr name="popupTextAlignment" format="enum">

            <enum name="start" value="0" />

            <enum name="end" value="1" />

            <enum name="center" value="2" />

        <attr name="isPutByDef" format="boolean" />

        <attr name="isMultiple" format="boolean"/>

        <attr name="delimiter" format="string"/>

    </declare-styleable>

    public class NiceSpinnerextends AppCompatTextView {

    private static final int MAX_LEVEL =10000;

        private static final int DEFAULT_ELEVATION =16;

        private static final StringINSTANCE_STATE ="instance_state";

        private static final StringSELECTED_INDEX ="selected_index";

        private static final StringIS_POPUP_SHOWING ="is_popup_showing";

        private static final StringIS_ARROW_HIDDEN ="is_arrow_hidden";

        private static final StringARROW_DRAWABLE_RES_ID ="arrow_drawable_res_id";

        public static final int VERTICAL_OFFSET =1;

        private int selectedIndex = -1;

        private DrawablearrowDrawable;

        private PopupWindowpopupWindow;

        private ListViewlistView;

        private NiceSpinnerBaseAdapteradapter;

        private AdapterView.OnItemClickListeneronItemClickListener;

        private AdapterView.OnItemSelectedListeneronItemSelectedListener;

        private OnItemCheckedListeneronItemCheckedListener;

        private boolean isArrowHidden;

        private int textColor;

        private int backgroundSelector;

        private int arrowDrawableTint;

        private int displayHeight;

        private int parentVerticalOffset;

        private int dropDownListPaddingBottom;

        private @DrawableRes

        int arrowDrawableResId;

        private SpinnerTextFormatterspinnerTextFormatter =new SimpleSpinnerTextFormatter<>();

        private SpinnerTextFormatterselectedTextFormatter =new SimpleSpinnerTextFormatter<>();

        private PopUpTextAlignmenthorizontalAlignment;

        private boolean isPutByDef =true;

        private StringdefText;

        private boolean isMultiple =false;

        private Stringdelimiter =",";

        public NiceSpinner(Context context) {

    super(context);

            init(context, null);

        }

    public NiceSpinner(Context context, AttributeSet attrs) {

    super(context, attrs);

            init(context, attrs);

        }

    public NiceSpinner(Context context, AttributeSet attrs, int defStyleAttr) {

    super(context, attrs, defStyleAttr);

            init(context, attrs);

        }

    @Override

        public ParcelableonSaveInstanceState() {

    Bundle bundle =new Bundle();

            bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());

            bundle.putInt(SELECTED_INDEX, selectedIndex);

            bundle.putBoolean(IS_ARROW_HIDDEN, isArrowHidden);

            bundle.putInt(ARROW_DRAWABLE_RES_ID, arrowDrawableResId);

            if (popupWindow !=null) {

    bundle.putBoolean(IS_POPUP_SHOWING, popupWindow.isShowing());

            }

    return bundle;

        }

    @Override

        public void onRestoreInstanceState(Parcelable savedState) {

    if (savedStateinstanceof Bundle) {

    Bundle bundle = (Bundle) savedState;

                selectedIndex = bundle.getInt(SELECTED_INDEX);

                if (adapter !=null) {

    setSelectText();

                    adapter.setSelectedIndex(selectedIndex);

                }

    if (bundle.getBoolean(IS_POPUP_SHOWING)) {

    if (popupWindow !=null) {

    // Post the show request into the looper to avoid bad token exception

                        post(new Runnable() {

    @Override

                            public void run() {

    showDropDown();

                            }

    });

                    }

    }

    isArrowHidden = bundle.getBoolean(IS_ARROW_HIDDEN, false);

                arrowDrawableResId = bundle.getInt(ARROW_DRAWABLE_RES_ID);

                savedState = bundle.getParcelable(INSTANCE_STATE);

            }

    super.onRestoreInstanceState(savedState);

        }

    private void init(Context context, AttributeSet attrs) {

    Resources resources = getResources();

            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NiceSpinner);

    /*        setPadding(resources.getDimensionPixelSize(R.dimen.dp_10), 0, 0,

    0);*/

            setClickable(true);

            backgroundSelector = typedArray.getResourceId(R.styleable.NiceSpinner_backgroundSelector, R.drawable.selector);

    //        setBackgroundResource(backgroundSelector);

            textColor = typedArray.getColor(R.styleable.NiceSpinner_textTint, getDefaultTextColor(context));

            isPutByDef = typedArray.getBoolean(R.styleable.NiceSpinner_isPutByDef, true);

            isMultiple = typedArray.getBoolean(R.styleable.NiceSpinner_isMultiple, false);

            delimiter = typedArray.getString(R.styleable.NiceSpinner_delimiter);

            if (delimiter ==null) {

    delimiter =",";

            }

    defText = getText().toString();

            setTextColor(textColor);

            listView =new ListView(context);

            // Set the spinner's id into the listview to make it pretend to be the right parent in

    // onItemClick

            listView.setId(getId());

            listView.setDivider(null);

            listView.setItemsCanFocus(true);

            listView.setVerticalScrollBarEnabled(true);

            listView.setHorizontalScrollBarEnabled(false);

            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

    @Override

                public void onItemClick(AdapterView parent, View view, int position, long id) {

    /*                if (position >= selectedIndex && position < adapter.getCount()) {

    position++;

    }*/

    // Need to set selected index before calling listeners or getSelectedIndex() can be

    // reported incorrectly due to race conditions.

                    if (isMultiple) {

    adapter.setCheckedIndex(position);

                    }else {

    adapter.setSelectedIndex(position);

                        selectedIndex = position;

                    }

    if (onItemClickListener !=null) {

    onItemClickListener.onItemClick(parent, view, position, id);

                    }

    if (onItemSelectedListener !=null && !isMultiple) {

    onItemSelectedListener.onItemSelected(parent, view, position, id);

                    }

    if (onItemCheckedListener !=null &&isMultiple) {

    onItemCheckedListener.onItemChecked(parent, view, adapter.getChecked());

                    }

    setSelectText();

                    if (!isMultiple) {

    dismissDropDown();

                    }

    }

    });

            popupWindow =new PopupWindow(context);

            popupWindow.setContentView(listView);

            popupWindow.setOutsideTouchable(true);

            popupWindow.setFocusable(true);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

    popupWindow.setElevation(DEFAULT_ELEVATION);

                popupWindow.setBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.spinner_drawable));

            }else {

    popupWindow.setBackgroundDrawable(ContextCompat.getDrawable(context, R.drawable.drop_down_shadow));

            }

    popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {

    @Override

                public void onDismiss() {

    if (!isArrowHidden) {

    animateArrow(false);

                    }

    }

    });

            isArrowHidden = typedArray.getBoolean(R.styleable.NiceSpinner_hideArrow, false);

            arrowDrawableTint = typedArray.getColor(R.styleable.NiceSpinner_arrowTint, Integer.MAX_VALUE);

            arrowDrawableResId = typedArray.getResourceId(R.styleable.NiceSpinner_arrowDrawable, R.drawable.arrow);

            dropDownListPaddingBottom =

    typedArray.getDimensionPixelSize(R.styleable.NiceSpinner_dropDownListPaddingBottom, 0);

            horizontalAlignment = PopUpTextAlignment.fromId(

    typedArray.getInt(R.styleable.NiceSpinner_popupTextAlignment, PopUpTextAlignment.CENTER.ordinal())

    );

            switch (horizontalAlignment) {

    case END:

    setGravity(Gravity.CENTER_VERTICAL | Gravity.END);

    break;

                case START:

    setGravity(Gravity.CENTER_VERTICAL | Gravity.START);

    break;

                case CENTER:

    setGravity(Gravity.CENTER);

    break;

            }

    typedArray.recycle();

            measureDisplayHeight();

        }

    private void measureDisplayHeight() {

    displayHeight = getContext().getResources().getDisplayMetrics().heightPixels;

        }

    private int getParentVerticalOffset() {

    if (parentVerticalOffset >0) {

    return parentVerticalOffset;

            }

    int[] locationOnScreen =new int[2];

            getLocationOnScreen(locationOnScreen);

            return parentVerticalOffset = locationOnScreen[VERTICAL_OFFSET];

        }

    @Override

        protected void onVisibilityChanged(View changedView, int visibility) {

    super.onVisibilityChanged(changedView, visibility);

            arrowDrawable = initArrowDrawable(arrowDrawableTint);

            setArrowDrawableOrHide(arrowDrawable);

        }

    private DrawableinitArrowDrawable(int drawableTint) {

    Drawable drawable = ContextCompat.getDrawable(getContext(), arrowDrawableResId);

            if (drawable !=null) {

    drawable = DrawableCompat.wrap(drawable);

                if (drawableTint != Integer.MAX_VALUE && drawableTint !=0) {

    DrawableCompat.setTint(drawable, drawableTint);

                }

    }

    return drawable;

        }

    private void setArrowDrawableOrHide(Drawable drawable) {

    if (!isArrowHidden && drawable !=null) {

    setCompoundDrawablesWithIntrinsicBounds(null, null, drawable, null);

            }else {

    setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);

            }

    }

    private int getDefaultTextColor(Context context) {

    TypedValue typedValue =new TypedValue();

            context.getTheme()

    .resolveAttribute(android.R.attr.textColorPrimary, typedValue, true);

            TypedArray typedArray = context.obtainStyledAttributes(typedValue.data,

                    new int[]{android.R.attr.textColorPrimary});

            int defaultTextColor = typedArray.getColor(0, Color.BLACK);

            typedArray.recycle();

            return defaultTextColor;

        }

    public int getSelectedIndex() {

    return selectedIndex;

        }

    public SetgetCheckIndex() {

    return adapter !=null ?adapter.getChecked() :null;

        }

    public T getSelectItem() {

    if (adapter !=null &&selectedIndex > -1 &&selectedIndex

    return adapter.getItem(selectedIndex);

            }

    return null;

        }

    public ListgetCheckItem() {

    List checkItem =new ArrayList<>();

            if (isMultiple &&adapter !=null) {

    for (Integer integer :adapter.getChecked()) {

    if (integer > -1 && integer

    checkItem.add(adapter.getItem(integer));

                    }

    }

    }

    return checkItem;

        }

    public int getCount() {

    if (adapter !=null) {

    return adapter.getCount();

            }else {

    return 0;

            }

    }

    public void setArrowDrawable(@DrawableRes @ColorRes int drawableId) {

    arrowDrawableResId = drawableId;

            arrowDrawable = initArrowDrawable(R.drawable.arrow);

            setArrowDrawableOrHide(arrowDrawable);

        }

    public void setArrowDrawable(Drawable drawable) {

    arrowDrawable = drawable;

            setArrowDrawableOrHide(arrowDrawable);

        }

    private void setSelectText() {

    if (adapter ==null) {

    return;

            }

    if (isMultiple) {

    List selectItem =new ArrayList<>();

                for (Integer integer :adapter.getChecked()) {

    selectItem.add(adapter.getItem(integer));

                }

    setMultipleTextInternal(selectItem);

            }else {

    if (selectedIndex >=0 &&selectedIndex

    setTextInternal(adapter.getItemInDataset(selectedIndex));

            }

    }

    public void setMultipleTextInternal(List data) {

    StringBuilder selectText =new StringBuilder();

            for (T datum : data) {

    CharSequence text ="";

                if (selectedTextFormatter !=null) {

    text =selectedTextFormatter.format(datum);

                }else if (spinnerTextFormatter !=null) {

    text =spinnerTextFormatter.format(datum);

                }

    selectText.append(",").append(text);

            }

    if (selectText.length() >0) {

    selectText.deleteCharAt(0);

            }

    setText(selectText);

        }

    public void setTextInternal(T data) {

    if (selectedTextFormatter !=null) {

    setText(selectedTextFormatter.format(data));

            }else if (spinnerTextFormatter !=null) {

    setText(spinnerTextFormatter.format(data));

            }else {

    setText(data.toString());

            }

    }

    /**

    * Set the default spinner item using its index

    *

        * @param position the item's position

    */

        public void setSelectedIndex(int position) {

    if (adapter !=null) {

    if (position >=0 && position

    adapter.setSelectedIndex(position);

                    selectedIndex = position;

                    if (onItemSelectedListener !=null &&listView !=null) {

    onItemSelectedListener.onItemSelected(listView,

                                listView.getChildAt(position -listView.getFirstVisiblePosition()),

                                position, adapter.getItemId(position));

                    }

    setSelectText();

                }else {

    throw new IllegalArgumentException("Position must be lower than adapter count!");

                }

    }

    }

    /**

    * Set the default spinner item using its index

    *

        * @param position the item's position

    */

        public void setCheckedIndex(int position) {

    if (adapter !=null) {

    if (position >=0 && position <=adapter.getCount()) {

    adapter.setCheckedIndex(position);

                    if (onItemCheckedListener !=null &&listView !=null) {

    onItemCheckedListener.onItemChecked(listView,

                                listView.getChildAt(position -listView.getFirstVisiblePosition()),

                                adapter.getChecked());

                    }

    setSelectText();

                }else {

    throw new IllegalArgumentException("Position must be lower than adapter count!");

                }

    }

    }

    public void addOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) {

    this.onItemClickListener = onItemClickListener;

        }

    public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener onItemSelectedListener) {

    this.onItemSelectedListener = onItemSelectedListener;

        }

    public OnItemCheckedListenergetOnItemCheckedListener() {

    return onItemCheckedListener;

        }

    public void setOnItemCheckedListener(OnItemCheckedListener onItemCheckedListener) {

    this.onItemCheckedListener = onItemCheckedListener;

        }

    public boolean isMultiple() {

    return isMultiple;

        }

    public void setMultiple(boolean multiple) {

    isMultiple = multiple;

        }

    public void attachData(List list) {

    adapter =new NiceSpinnerAdapter<>(getContext(), list, textColor, backgroundSelector, spinnerTextFormatter, horizontalAlignment);

            setAdapterInternal(adapter);

        }

    public boolean isPutByDef() {

    return isPutByDef;

        }

    public void attachDataSource(List list) {

    if (isPutByDef) {

    if (!list.contains(getText().toString())) {

    list.add(0, getText().toString());

                }

    }

    attachData(list);

        }

    @Override

        public void setText(CharSequence text, BufferType type) {

    if (TextUtils.isEmpty(text) &&isPutByDef) {

    text =defText;

            }

    super.setText(text, type);

        }

    public void setAdapter(ListAdapter adapter) {

    this.adapter =new NiceSpinnerAdapterWrapper(getContext(), adapter, textColor, backgroundSelector,

                    spinnerTextFormatter, horizontalAlignment);

            setAdapterInternal(this.adapter);

        }

    public PopUpTextAlignmentgetPopUpTextAlignment() {

    return horizontalAlignment;

        }

    private void setAdapterInternal(NiceSpinnerBaseAdapter adapter) {

    // If the adapter needs to be settled again, ensure to reset the selected index as well

            if (isMultiple) {

    adapter.setChecked(new HashSet<>());

            }else {

    if (adapter.getCount() >0) {

    selectedIndex =0;

                    adapter.setSelectedIndex(0);

                }

    }

    listView.setAdapter(adapter);

            setSelectText();

        }

    @Override

        public boolean onTouchEvent(MotionEvent event) {

    if (isEnabled() && event.getAction() == MotionEvent.ACTION_UP) {

    if (!popupWindow.isShowing()) {

    showDropDown();

                }else {

    dismissDropDown();

                }

    }

    return super.onTouchEvent(event);

        }

    private void animateArrow(boolean shouldRotateUp) {

    //由于多个下拉单选框会互相影响,暂时关闭动画

            if (true) {

    return;

            }

    int start = shouldRotateUp ?0 :MAX_LEVEL;

            int end = shouldRotateUp ?MAX_LEVEL :0;

            ObjectAnimator animator = ObjectAnimator.ofInt(arrowDrawable, "level", start, end);

            animator.setInterpolator(new LinearOutSlowInInterpolator());

            animator.start();

        }

    public void dismissDropDown() {

    if (!isArrowHidden) {

    animateArrow(false);

            }

    popupWindow.dismiss();

        }

    public void showDropDown() {

    if (!isArrowHidden) {

    animateArrow(true);

            }

    measurePopUpDimension();

            popupWindow.showAsDropDown(this);

        }

    private void measurePopUpDimension() {

    int widthSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY);

            int heightSpec = MeasureSpec.makeMeasureSpec(getPopUpHeight(), MeasureSpec.AT_MOST);

            listView.measure(widthSpec, heightSpec);

            popupWindow.setWidth(listView.getMeasuredWidth());

            popupWindow.setHeight(listView.getMeasuredHeight() -dropDownListPaddingBottom);

        }

    private int getPopUpHeight() {

    return Math.max(verticalSpaceBelow(), verticalSpaceAbove());

        }

    private int verticalSpaceAbove() {

    return getParentVerticalOffset();

        }

    private int verticalSpaceBelow() {

    return displayHeight - getParentVerticalOffset() - getMeasuredHeight();

        }

    public void setTintColor(@ColorRes int resId) {

    if (arrowDrawable !=null && !isArrowHidden) {

    DrawableCompat.setTint(arrowDrawable, ContextCompat.getColor(getContext(), resId));

            }

    }

    public void setArrowTintColor(int resolvedColor) {

    if (arrowDrawable !=null && !isArrowHidden) {

    DrawableCompat.setTint(arrowDrawable, resolvedColor);

            }

    }

    public void hideArrow() {

    isArrowHidden =true;

            setArrowDrawableOrHide(arrowDrawable);

        }

    public void showArrow() {

    isArrowHidden =false;

            setArrowDrawableOrHide(arrowDrawable);

        }

    public boolean isArrowHidden() {

    return isArrowHidden;

        }

    public void setDropDownListPaddingBottom(int paddingBottom) {

    dropDownListPaddingBottom = paddingBottom;

        }

    public int getDropDownListPaddingBottom() {

    return dropDownListPaddingBottom;

        }

    public void setSpinnerTextFormatter(SpinnerTextFormatter textFormatter) {

    this.spinnerTextFormatter = textFormatter;

        }

    public void setSelectedTextFormatter(SpinnerTextFormatter textFormatter) {

    this.selectedTextFormatter = textFormatter;

        }

    public interface OnItemCheckedListener {

    void onItemChecked(AdapterView parent, View view, Set positions);

        }

    }

    public class UIRoundButtonextends UIAlphaButton {

    public UIRoundButton(Context context) {

    super(context);

            init(context, null, 0);

        }

    public UIRoundButton(Context context, AttributeSet attrs) {

    super(context, attrs, R.attr.UIButtonStyle);

            init(context, attrs, R.attr.UIButtonStyle);

        }

    public UIRoundButton(Context context, AttributeSet attrs, int defStyleAttr) {

    super(context, attrs, defStyleAttr);

            init(context, attrs, defStyleAttr);

        }

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {

    UIRoundButtonDrawable bg = UIRoundButtonDrawable.fromAttributeSet(context, attrs, defStyleAttr);

            ViewUtil.setBackgroundKeepingPadding(this, bg);

            setChangeAlphaWhenDisable(false);

            setChangeAlphaWhenPress(false);

        }

    }

    public class GsonTypeAdaptorextends TypeAdapter {

    @Override

        public Objectread(JsonReader in)throws IOException {

    JsonToken token = in.peek();

            switch (token) {

    case BEGIN_ARRAY:

    List list =new ArrayList();

                    in.beginArray();

                    while (in.hasNext()) {

    list.add(read(in));

                    }

    in.endArray();

                    return list;

                case BEGIN_OBJECT:

    Map map =new LinkedTreeMap();

                    in.beginObject();

                    while (in.hasNext()) {

    map.put(in.nextName(), read(in));

                    }

    in.endObject();

                    return map;

                case STRING:

    return in.nextString();

                case NUMBER:

    /**

                    * 改写数字的处理逻辑,将数字值分为整型与浮点型。

                    */

                    double dbNum = in.nextDouble();

                    // 数字超过long的最大值,返回浮点类型

                    if (dbNum > Long.MAX_VALUE) {

    return dbNum;

                    }

    // 判断数字是否为整数值

                    long lngNum = (long) dbNum;

                    if (dbNum == lngNum) {

    return lngNum;

                    }else {

    return dbNum;

                    }

    case BOOLEAN:

    return in.nextBoolean();

                case NULL:

    in.nextNull();

    return null;

                default:

    throw new IllegalStateException();

            }

    }

    @Override

        public void write(JsonWriter out, Object value)throws IOException {

    // 序列化无需实现

        }

    }

    public class GsonTypeAdaptorextends TypeAdapter {

    @Override

        public Objectread(JsonReader in)throws IOException {

    JsonToken token = in.peek();

            switch (token) {

    case BEGIN_ARRAY:

    List list =new ArrayList();

                    in.beginArray();

                    while (in.hasNext()) {

    list.add(read(in));

                    }

    in.endArray();

                    return list;

                case BEGIN_OBJECT:

    Map map =new LinkedTreeMap();

                    in.beginObject();

                    while (in.hasNext()) {

    map.put(in.nextName(), read(in));

                    }

    in.endObject();

                    return map;

                case STRING:

    return in.nextString();

                case NUMBER:

    /**

                    * 改写数字的处理逻辑,将数字值分为整型与浮点型。

                    */

                    double dbNum = in.nextDouble();

                    // 数字超过long的最大值,返回浮点类型

                    if (dbNum > Long.MAX_VALUE) {

    return dbNum;

                    }

    // 判断数字是否为整数值

                    long lngNum = (long) dbNum;

                    if (dbNum == lngNum) {

    return lngNum;

                    }else {

    return dbNum;

                    }

    case BOOLEAN:

    return in.nextBoolean();

                case NULL:

    in.nextNull();

    return null;

                default:

    throw new IllegalStateException();

            }

    }

    @Override

        public void write(JsonWriter out, Object value)throws IOException {

    // 序列化无需实现

        }

    }

    相关文章

      网友评论

          本文标题:测试

          本文链接:https://www.haomeiwen.com/subject/mknowttx.html