探索drawalbeTop的弊端到顶刷新只选择tab图标旋转文字不旋转动画方案

关于到顶部刷新的实现,可以查看我另外一篇文章

这里tab是使用的RadioGroup,很倔强的我坚持不使用第三方,自己折腾传统老套的selector来实现。

方案1 只修改DrawableRadioButton 和添加xml动画

那么想到的方案就是给drawableTop设置动画xml 布局。
结果发现不旋转,在网上找到了一个方案 继承它就可以实现旋转:

public class DrawableRadioButton extends android.support.v7.widget.AppCompatRadioButton {

    public DrawableRadioButton(Context context) {
        super(context);
    }

    public DrawableRadioButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public DrawableRadioButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    int textWidth;
    int textHeight;
    Drawable mDrawableLeft = null;
    int startDrawableX = 0;
    int startDrawableY = 0;

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        initText();
    }

    private void initText() {
        String textStr = super.getText().toString();
        Rect rect = new Rect();
        getPaint().getTextBounds(textStr, 0, textStr.length(), rect);
        getPaint().setColor(getTextColors().getDefaultColor());
        getPaint().setTextSize(getTextSize());
        textWidth = rect.width();
        textHeight = rect.height();

    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mDrawableLeft == null) mDrawableLeft = getCompoundDrawables()[0];

        if (mDrawableLeft == null) {
            super.onDraw(canvas);
            return;
        }
        int drawablePadding = getCompoundDrawablePadding();
        int drawableWidth = this.mDrawableLeft.getIntrinsicWidth();
        int drawableHeight = this.mDrawableLeft.getIntrinsicHeight();
        startDrawableX = (getWidth() >> 1) - ((drawablePadding + textWidth + drawableWidth) >> 1);
        startDrawableY = (getHeight() >> 1) - (drawableHeight >> 1);
        //画旋转图片
        canvas.save();
        canvas.translate(startDrawableX, startDrawableY);
        this.mDrawableLeft.draw(canvas);
        canvas.restore();

        //画文字
        int boxht = this.getMeasuredHeight() - this.getExtendedPaddingTop() - this.getExtendedPaddingBottom();
        int textht = getLayout().getHeight();
        int voffsetText = boxht - textht >> 1;
        canvas.save();
        canvas.translate((float) (startDrawableX + drawableWidth + drawablePadding), (float) (getExtendedPaddingTop() + voffsetText));
        getLayout().draw(canvas);
        canvas.restore();
    }

    @Override
    public void invalidateDrawable(Drawable drawable) {
//        super.invalidateDrawable(drawable);
        final Rect dirty = drawable.getBounds();
        int scrollX = 0;
        int scrollY = 0;
        if (drawable == this.mDrawableLeft) {
            scrollX = startDrawableX;
            scrollY = startDrawableY;
        }
        this.invalidate(dirty.left + scrollX - 2, dirty.top + scrollY - 2, dirty.right + scrollX + 2, dirty.bottom + scrollY + 2);
    }

    public Drawable getDrawableLeft() {
        return mDrawableLeft;
    }

}

缺点 旋转速度不可以调节,旋转速度非常慢

方案2 使用我我之前写的RadioGroupX少量的改动实现 且还兼容原来的RadioButton

这种方法又是要手写一个RadioButton了,我在这里称之

为DrawableTopRadioButton
如何实现的如果喜欢看源码的直接点击源码,下面我来说说我踩到的坑

大致原理就是添加一个相对布局然后从上大小放入图片控件和RadioButton控件 然后小红点依然支持,所以我是从小红点view拷贝过来的.我自己写的代码我也不想重写啊,这么多属性,多累啊

踩坑1 添加上去是空白,文字和图片都不显示.

我在做这个的时候浪费了太多时间了,因为我拷贝我另外一份自己写的,实际上是自定义的drawableTop和自定义的text属性,我傻乎乎的一直用android:textandroid:drawableTop 结果一直空白,郁闷死了, 用分析层级工具查看也竟然出现各种奇葩的问题,也并没有说添加进去了,而且竟然提示还是之前写的LinearLayout 我明明改成RelativeLayout了的然后各种编译,漫长的时间,最后受不到了,我直接跑模块运行提升速度, 总之太复杂太粗心了,结果浪费了1上午时间才恍然大悟,我还以为是编译器出毛病了,明明添加进去了竟然用分析工具看不到child节点,包括断点调试也没发现问题..结果是直接把第三个支持小红点的配置弄进去发现预览都出效果了,果然就好了.

踩坑2 不能使用传统的findById找 index了

选中内部的radiobutton 然后用group.indexOf() findById()一直找不到child.导致idnex=-1解决方法给内部的radiobutton设置的id,和这个DrawableTopRadioButton的id一样,为何只能这样原因也是为了兼容某个接口不得不这么做,这个接口必须实现void onCheckedChanged(CompoundButton buttonView, boolean isChecked);我内部回传的时候传递的是只能传递内部的RadioButton 因为它才是继承CompoundButton的,如果不这样传递,那么又要修改大量源码.而且很难兼容系统的RadioButton
在系统的RadioGroup有这么一段代码

    private class CheckedStateTracker implements CompoundButton.OnCheckedChangeListener {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            // prevents from infinite recursion
            if (mProtectFromCheckedChange) {
                return;
            }

            mProtectFromCheckedChange = true;
            if (mCheckedId != -1) {
                setCheckedStateForView(mCheckedId, false);
            }
            mProtectFromCheckedChange = false;

            int id = buttonView.getId();
            setCheckedId(id);
        }
    }

这里在初始化的时候就添加了一个监听,所以我不能大改动,但是又要再触发的时候传递一个CompoundButton又要让findById 也能找到对应的索引,我就只能把内部的RadioButton当做替身传递进去.

踩坑3 imageview不能使用select选择器导致点图片无法选中tab改变颜色

经过万能的搜索找到了相关的代码 也就是说要实现Checkable才能实现选择器的.所以给它正好之后,改成单选,就完事
具体怎么实现看源码

踩坑4 点击图片并不能进行排斥,虽然选中了,但是没回调。

解决方案
给图片设置一个点击事件,然后点击之后手动调用radiobutton的setCheck方法. 因为这里绑定的是radioButton能进行排斥的只有它,而且排斥也是根据id来的

踩坑5 不能点击图片或者点击、双击 radiobutton进行点击刷新 到顶部

这个问题是因为我是给DrawableTopRadioButton添加的触摸事件,如果有这种需求的朋友,直接继承DrawableTopRadioButton复写onInterceptTouchEvent方法返回true,然后在手势里面做一些操作,包括单击的时候手动调用DrawableTopRadioButton.getRadioButton().setCheck(true)以及调用DrawableTopRadioButton.getTopImageView().setCheck(true)就可以解决这个更加变态的需求了,这个需求了
或者也可以给imageView和RadioButton也添加一个触摸事件类,这个类和DrawableTopRadioButton的触摸事件类一样,这里看不懂的朋友看我另外一篇文章,叫到顶刷新实现方案

吐槽

坑已经帮大家踩完了但是,我搞这个花了很多时间的,如果要用第三方,或者手写一个 多加一点判断也是可以实现的,怪我太执着 硬是折腾RadioGroup 不过总算搞定了所有的变态需求啦!!!要研究如何修改RadioGroup进行扩展的朋友可以点击android分类查看我的另外的一篇文章.

你可能感兴趣的:(探索drawalbeTop的弊端到顶刷新只选择tab图标旋转文字不旋转动画方案)