TextBannerView icon indicating copy to clipboard operation
TextBannerView copied to clipboard

关于嵌套在Fragment的bug

Open 13389809 opened this issue 5 years ago • 1 comments

四个Fragment, 轮播放在第三个里。 切换123都没问题,切换到第四个再回来,轮播貌似还在继续,但是轮播到下一个就会丢失。

13389809 avatar Jul 02 '19 03:07 13389809

adapter中:

    public void onViewAttachedToWindow(BaseViewHolder holder) {
        super.onViewAttachedToWindow(holder);
        startViewAnimator();
    }

fragment:

onHiddenChanged
setUserVisibleHint
onPause

中增加控制停止和开始的操作,应该可以解决问题。我目前看了bug表,他们遇到问题,我基本上之前遇到过,现在我按照上面的方法处理了,就没有了。 不过我是修改了源码,然后配合上面的处理的。

public class TextBannerView extends RelativeLayout {
    private ViewFlipper mViewFlipper;
    private int mInterval = 3000;
    /**
     * 文字切换时间间隔,默认3s
     */
    private boolean isSingleLine = false;
    /**
     * 文字是否为单行,默认false
     */
    private int mTextColor = 0xff000000;
    /**
     * 设置文字颜色,默认黑色
     */
    private int mTextSize = 16;
    /**
     * 设置文字尺寸,默认16px
     */
    private int mGravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
    /**
     * 文字显示位置,默认左边居中
     */
    private static final int GRAVITY_LEFT = 0;
    private static final int GRAVITY_CENTER = 1;
    private static final int GRAVITY_RIGHT = 2;

    private boolean hasSetDirection = false;
    private int direction = DIRECTION_BOTTOM_TO_TOP;
    private static final int DIRECTION_BOTTOM_TO_TOP = 0;
    private static final int DIRECTION_TOP_TO_BOTTOM = 1;
    private static final int DIRECTION_RIGHT_TO_LEFT = 2;
    private static final int DIRECTION_LEFT_TO_RIGHT = 3;
    @AnimRes
    private int inAnimResId = R.anim.anim_right_in;
    @AnimRes
    private int outAnimResId = R.anim.anim_left_out;
    private boolean hasSetAnimDuration = false;
    private int animDuration = 1500;
    /**
     * 默认1.5s
     */
    private int mFlags = -1;
    /**
     * 文字划线
     */
    private static final int STRIKE = 0;
    private static final int UNDER_LINE = 1;
    private int mTypeface = Typeface.NORMAL;
    /**
     * 设置字体类型:加粗、斜体、斜体加粗
     */
    private static final int TYPE_NORMAL = 0;
    private static final int TYPE_BOLD = 1;
    private static final int TYPE_ITALIC = 2;
    private static final int TYPE_ITALIC_BOLD = 3;

    private List<String> mDatas;
    private ITextBannerItemClickListener mListener;
    private boolean isStarted;
    private boolean isDetachedFromWindow;


    public interface ITextBannerItemClickListener {
        /**
         * onItemClick
         *
         * @param data
         * @param position
         */
        void onItemClick(String data, int position);
    }

    public TextBannerView(Context context) {
        this(context, null);
    }

    public TextBannerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    /**
     * 初始化控件
     */
    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TextBannerViewStyle, defStyleAttr, 0);
        //文字切换时间间隔
        mInterval = typedArray.getInteger(R.styleable.TextBannerViewStyle_setInterval, mInterval);
        //文字是否为单行
        isSingleLine = typedArray.getBoolean(R.styleable.TextBannerViewStyle_setSingleLine, false);
        //设置文字颜色
        mTextColor = typedArray.getColor(R.styleable.TextBannerViewStyle_setTextColor, mTextColor);
        //设置文字尺寸
        if (typedArray.hasValue(R.styleable.TextBannerViewStyle_setTextSize)) {
            mTextSize = (int) typedArray.getDimension(R.styleable.TextBannerViewStyle_setTextSize, mTextSize);
            mTextSize = DisplayUtils.px2sp(context, mTextSize);
        }
        //显示位置
        int gravityType = typedArray.getInt(R.styleable.TextBannerViewStyle_setGravity, GRAVITY_LEFT);
        switch (gravityType) {
            case GRAVITY_LEFT:
                mGravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
                break;
            case GRAVITY_CENTER:
                mGravity = Gravity.CENTER;
                break;
            case GRAVITY_RIGHT:
                mGravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
                break;
            default:
        }
        hasSetAnimDuration = typedArray.hasValue(R.styleable.TextBannerViewStyle_setAnimDuration);
        //动画时间
        animDuration = typedArray.getInt(R.styleable.TextBannerViewStyle_setAnimDuration, animDuration);
        hasSetDirection = typedArray.hasValue(R.styleable.TextBannerViewStyle_setDirection);
        //方向
        direction = typedArray.getInt(R.styleable.TextBannerViewStyle_setDirection, direction);
        if (hasSetDirection) {
            switch (direction) {
                case DIRECTION_BOTTOM_TO_TOP:
                    inAnimResId = R.anim.anim_bottom_in;
                    outAnimResId = R.anim.anim_top_out;
                    break;
                case DIRECTION_TOP_TO_BOTTOM:
                    inAnimResId = R.anim.anim_top_in;
                    outAnimResId = R.anim.anim_bottom_out;
                    break;
                case DIRECTION_RIGHT_TO_LEFT:
                    inAnimResId = R.anim.anim_right_in;
                    outAnimResId = R.anim.anim_left_out;
                    break;
                case DIRECTION_LEFT_TO_RIGHT:
                    inAnimResId = R.anim.anim_left_in;
                    outAnimResId = R.anim.anim_right_out;
                    break;
                default:
            }
        } else {
            inAnimResId = R.anim.anim_right_in;
            outAnimResId = R.anim.anim_left_out;
        }
        //字体划线
        mFlags = typedArray.getInt(R.styleable.TextBannerViewStyle_setFlags, mFlags);
        switch (mFlags) {
            case STRIKE:
                mFlags = Paint.STRIKE_THRU_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG;
                break;
            case UNDER_LINE:
                mFlags = Paint.UNDERLINE_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG;
                break;
            default:
                mFlags = 0 | Paint.ANTI_ALIAS_FLAG;
                break;
        }
        //字体样式
        mTypeface = typedArray.getInt(R.styleable.TextBannerViewStyle_setTypeface, mTypeface);
        switch (mTypeface) {
            case TYPE_BOLD:
                mTypeface = Typeface.BOLD;
                break;
            case TYPE_ITALIC:
                mTypeface = Typeface.ITALIC;
                break;
            case TYPE_ITALIC_BOLD:
                mTypeface = Typeface.ITALIC | Typeface.BOLD;
                break;
            default:
                break;
        }

        //new 一个ViewAnimator
        mViewFlipper = new ViewFlipper(getContext());
        mViewFlipper.setLayoutParams(
                new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        addView(mViewFlipper);
        startViewAnimator();
        //设置点击事件
        mViewFlipper.setOnClickListener(v -> {
            //当前显示的子视图的索引位置
            int position = mViewFlipper.getDisplayedChild();
            if (mListener != null && mDatas.size() > 0) {
                mListener.onItemClick(mDatas.get(position), position);
            }
        });

    }

    public ViewFlipper getViewFlipper() {
        return mViewFlipper;
    }

    /**
     * 暂停动画
     */
    public void stopViewAnimator() {
        //if (isStarted) {
        if (mRunnable != null) {
            if (removeCallbacks(mRunnable)) {
                //L.e("跑马灯: ---- stop ----");
            }
        }
        isStarted = false;
        //}
    }

    /**
     * 开始动画
     */
    public void startViewAnimator() {
        if (!isStarted) {
            if (!isDetachedFromWindow) {
                isStarted = true;
                if (mRunnable != null) {
                    if (removeCallbacks(mRunnable)) {
                        postDelayed(mRunnable, mInterval);
                    }
                }
            }
        }
    }

    /**
     * 设置延时间隔
     */
    private AnimRunnable mRunnable = new AnimRunnable();

    private class AnimRunnable implements Runnable {

        @Override
        public void run() {
            if (isStarted && mDatas != null && !mDatas.isEmpty()) {
                setInAndOutAnimation(inAnimResId, outAnimResId);
                //手动显示下一个子view。
                mViewFlipper.showNext();
                postDelayed(this, mInterval + animDuration);
            } else {
                stopViewAnimator();
            }

        }
    }


    /**
     * 设置进入动画和离开动画
     *
     * @param inAnimResId  进入动画的resID
     * @param outAnimResID 离开动画的resID
     */
    private void setInAndOutAnimation(@AnimRes int inAnimResId, @AnimRes int outAnimResID) {
        Animation inAnim = AnimationUtils.loadAnimation(getContext(), inAnimResId);
        inAnim.setDuration(animDuration);
        mViewFlipper.setInAnimation(inAnim);

        Animation outAnim = AnimationUtils.loadAnimation(getContext(), outAnimResID);
        outAnim.setDuration(animDuration);
        mViewFlipper.setOutAnimation(outAnim);
    }


    /**
     * 设置数据集合
     */
    public void setDatas(List<String> datas) {
        this.mDatas = datas;
        if (mDatas != null && !mDatas.isEmpty()) {
            mViewFlipper.removeAllViews();
            for (int i = 0; i < mDatas.size(); i++) {
                TextView textView = new TextView(getContext());
                setTextView(textView, i);
                //添加子view,并标识子view位置
                mViewFlipper.addView(textView, i);
            }
        }

    }

    /**
     * 设置数据集合伴随drawable-icon
     * 暂时不能用
     *
     * @param datas 数据
     */
    public void setDatasWithDrawableIcon(List<String> datas, Drawable leftDrawable, Drawable topDrawable, Drawable rightDrawable, Drawable bottomDrawable) {
        this.mDatas = datas;
        if (mDatas != null && !mDatas.isEmpty()) {
            return;
        }
        mViewFlipper.removeAllViews();
        for (int i = 0; i < mDatas.size(); i++) {
            LinearLayout linearLayout = new LinearLayout(getContext());
            linearLayout.setBackgroundColor(Color.parseColor("#ccacbb"));
            linearLayout.setOrientation(LinearLayout.HORIZONTAL);
            linearLayout.setGravity(mGravity);
            LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(LinearLayout.
                    LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);

            TextView textView = new TextView(getContext());
            textView.setBackgroundColor(Color.parseColor("#3086F3"));
            setTextView(textView, i);
            textView.setCompoundDrawablePadding(8);
            textView.setCompoundDrawables(leftDrawable, topDrawable, rightDrawable, bottomDrawable);
            linearLayout.addView(textView, param);

            mViewFlipper.addView(linearLayout, i);
        }
    }

    /**
     * 设置TextView
     */
    private void setTextView(TextView textView, int position) {
        textView.setText(mDatas.get(position));
        //任意设置你的文字样式,在这里
        textView.setSingleLine(isSingleLine);
        textView.setEllipsize(TextUtils.TruncateAt.END);
        textView.setTextColor(mTextColor);
        textView.setTextSize(mTextSize);
        textView.setGravity(mGravity);
        //字体划线
        textView.getPaint().setFlags(mFlags);
        //字体样式
        textView.setTypeface(null, mTypeface);
    }


    /**
     * 设置点击监听事件回调
     */
    public void setItemOnClickListener(ITextBannerItemClickListener listener) {
        this.mListener = listener;
    }


    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        isDetachedFromWindow = true;
        stopViewAnimator();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        isDetachedFromWindow = false;
        //startViewAnimator();
    }
}

df13954 avatar Jan 03 '20 07:01 df13954