BadgeView and SlidingTabStrip clicking error

自古美人都是妖i 提交于 2019-12-05 07:48:43

问题


i am using sliding tab from:

https://developer.android.com/samples/SlidingTabsBasic/src/com.example.android.common/view/SlidingTabLayout.html

and BadgeView from:

https://github.com/jgilfelt/android-viewbadger

i just add these lines of code to SlidingTabLayout to access each tab:

    public SlidingTabStrip getTabStrip() {
    return mTabStrip;
}

so in fragmenta i can use below code to add badgeview to each tab:

public class FragmentA extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View fragmentView = inflater.inflate(R.layout.fragment_a,container,false);

        Button b1 = (Button) fragmentView.findViewById(R.id.tab1_button_fragmenta);
        b1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {

                View v = ((MainActivity)getActivity()).mSlidingTabLayout.getTabStrip().getChildAt(0);
                BadgeView badge = new BadgeView(getActivity(), v);
                badge.setText("1");
                badge.show();
            }
        });

        Button b2 = (Button) fragmentView.findViewById(R.id.tab2_button_fragmenta);
        b2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {

                View v = ((MainActivity)getActivity()).mSlidingTabLayout.getTabStrip().getChildAt(1);
                BadgeView badge = new BadgeView(getActivity(), v);
                badge.setText("2");
                badge.show();
            }
        });

        Button b3 = (Button) fragmentView.findViewById(R.id.tab3_button_fragmenta);
        b3.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {

                View v = ((MainActivity)getActivity()).mSlidingTabLayout.getTabStrip().getChildAt(2);
                BadgeView badge = new BadgeView(getActivity(), v);
                badge.setText("3");
                badge.show();
            }
        });

        return fragmentView;
    }

and the fragment layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFCC00" >

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_margin="16dp"
        android:text="This is Fragment A"
        android:textAppearance="?android:attr/textAppearanceLarge" />
   <Button
        android:id="@+id/tab1_button_fragmenta"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/textView"
        android:text="Add Badge To Tab 1" />

    <Button
        android:id="@+id/tab2_button_fragmenta"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tab1_button_fragmenta"
        android:text="Add Badge To Tab 2" />

    <Button
        android:id="@+id/tab3_button_fragmenta"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tab2_button_fragmenta"
        android:text="Add Badge To Tab 3" />


</RelativeLayout>

the result is:

but after i add BadgeView the functionality of clicking on tabs is gone. so i can not click on tabs to navigate to other pages. can anyone help me what to do?

here is main activity for those who just want to focus on solution and do not waste their time to create project:-)

public class MainActivity extends FragmentActivity {

    ViewPager viewPager=null;
    SlidingTabLayout mSlidingTabLayout = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewPager= (ViewPager) findViewById(R.id.pager);

       FragmentManager fm = getSupportFragmentManager();

        viewPager.setAdapter(new MyAdapter(fm));
        mSlidingTabLayout = (SlidingTabLayout)findViewById(R.id.sliding_tabs);
        mSlidingTabLayout.setViewPager(viewPager);

        viewPager.setAdapter(new MyAdapter(getSupportFragmentManager()));
        mSlidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int i, float v, int i2) {
            }

            @Override
            public void onPageSelected(int i) {
            }

            @Override
            public void onPageScrollStateChanged(int i) {

            }
        });




        }

class MyAdapter extends FragmentStatePagerAdapter
{

    public MyAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        Fragment fragment=null;
        if(i==0)
        {
            fragment=new FragmentA();
        }
        if(i==1)
        {
            fragment=new FragmentB();
        }
        if(i==2)
        {
            fragment=new FragmentC();
        }
        return fragment;
    }

    @Override
    public int getCount() {
        return 3;
    }
    @Override
    public CharSequence getPageTitle(int position) {
        return ("Tab" + position);
    }
}

}

and activity_main:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical">

    <com.example.tabbadge.SlidingTabLayout
          android:id="@+id/sliding_tabs"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
           />

<android.support.v4.view.ViewPager

    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</android.support.v4.view.ViewPager>
</LinearLayout>

回答1:


First of All:

Code:

1) Use this BadgeView Class instead of jar.

public class BadgeView extends TextView {

    public static final int POSITION_TOP_LEFT = 1;
    public static final int POSITION_TOP_RIGHT = 2;
    public static final int POSITION_BOTTOM_LEFT = 3;
    public static final int POSITION_BOTTOM_RIGHT = 4;
    public static final int POSITION_CENTER = 5;

    private static final int DEFAULT_MARGIN_DIP = 5;
    private static final int DEFAULT_LR_PADDING_DIP = 5;
    private static final int DEFAULT_CORNER_RADIUS_DIP = 8;
    private static final int DEFAULT_POSITION = POSITION_TOP_RIGHT;
    private static final int DEFAULT_BADGE_COLOR = Color
            .parseColor("#CCFF0000"); // Color.RED;
    private static final int DEFAULT_TEXT_COLOR = Color.WHITE;

    private static Animation fadeIn;
    private static Animation fadeOut;

    private Context context;
    private View target;

    private int badgePosition;
    private int badgeMarginH;
    private int badgeMarginV;
    private int badgeColor;

    private boolean isShown;

    private ShapeDrawable badgeBg;

    private int targetTabIndex;

    public BadgeView(Context context) {
        this(context, (AttributeSet) null, android.R.attr.textViewStyle);
    }

    public BadgeView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.textViewStyle);
    }

    /**
     * Constructor -
     * 
     * create a new BadgeView instance attached to a target
     * {@link android.view.View}.
     * 
     * @param context
     *            context for this view.
     * @param target
     *            the View to attach the badge to.
     */
    public BadgeView(Context context, View target) {
        this(context, null, android.R.attr.textViewStyle, target, 0);
    }

    /**
     * Constructor -
     * 
     * create a new BadgeView instance attached to a target
     * {@link android.widget.TabWidget} tab at a given index.
     * 
     * @param context
     *            context for this view.
     * @param target
     *            the TabWidget to attach the badge to.
     * @param index
     *            the position of the tab within the target.
     */
    public BadgeView(Context context, TabWidget target, int index) {
        this(context, null, android.R.attr.textViewStyle, target, index);
    }

    public BadgeView(Context context, AttributeSet attrs, int defStyle) {
        this(context, attrs, defStyle, null, 0);
    }

    public BadgeView(Context context, AttributeSet attrs, int defStyle,
            View target, int tabIndex) {
        super(context, attrs, defStyle);
        init(context, target, tabIndex);
    }

    public BadgeView(Context context, viewbadger.demo.SlidingTabStrip target,
            int i) {
        // TODO Auto-generated constructor stub
        this(context, null, android.R.attr.textViewStyle, target, i);
    }

    private void init(Context context, View target, int tabIndex) {

        this.context = context;
        this.target = target;
        this.targetTabIndex = tabIndex;

        // apply defaults
        badgePosition = DEFAULT_POSITION;
        badgeMarginH = dipToPixels(DEFAULT_MARGIN_DIP);
        badgeMarginV = badgeMarginH;
        badgeColor = DEFAULT_BADGE_COLOR;

        setTypeface(Typeface.DEFAULT_BOLD);
        int paddingPixels = dipToPixels(DEFAULT_LR_PADDING_DIP);
        setPadding(paddingPixels, 0, paddingPixels, 0);
        setTextColor(DEFAULT_TEXT_COLOR);

        fadeIn = new AlphaAnimation(0, 1);
        fadeIn.setInterpolator(new DecelerateInterpolator());
        fadeIn.setDuration(200);

        fadeOut = new AlphaAnimation(1, 0);
        fadeOut.setInterpolator(new AccelerateInterpolator());
        fadeOut.setDuration(200);

        isShown = false;

        if (this.target != null) {
            applyTo(this.target);
        } else {
            show();
        }

    }

    private void applyTo(View target) {

        LayoutParams lp = target.getLayoutParams();
        ViewParent parent = target.getParent();
        FrameLayout container = new FrameLayout(context);

        if (target instanceof TabWidget) {

            // set target to the relevant tab child container
            target = ((TabWidget) target).getChildTabViewAt(targetTabIndex);
            this.target = target;

            ((ViewGroup) target).addView(container, new LayoutParams(
                    LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

            this.setVisibility(View.GONE);
            container.addView(this);

        } else if (target instanceof SlidingTabStrip) {

            // set target to the relevant tab child container
            View textView = ((SlidingTabStrip) target)
                    .getChildAt(targetTabIndex);

            ViewGroup group = (ViewGroup) target;

            // getting index of TexTView from SlidingTabStrip
            int index = group.indexOfChild(textView);

            Log.e("index", "" + index);

            group.removeView(textView);
            group.addView(container, index, lp);

            container.addView(textView);

            this.setVisibility(View.GONE);
            container.addView(this);

            group.invalidate();

        } else {
            // TODO verify that parent is indeed a ViewGroup

            ViewGroup group = (ViewGroup) parent;
            int index = group.indexOfChild(target);

            group.removeView(target);
            group.addView(container, index, lp);

            container.addView(target);

            this.setVisibility(View.GONE);
            container.addView(this);

            group.invalidate();

        }

    }

    /**
     * Make the badge visible in the UI.
     * 
     */
    public void show() {
        show(false, null);
    }

    /**
     * Make the badge visible in the UI.
     * 
     * @param animate
     *            flag to apply the default fade-in animation.
     */
    public void show(boolean animate) {
        show(animate, fadeIn);
    }

    /**
     * Make the badge visible in the UI.
     * 
     * @param anim
     *            Animation to apply to the view when made visible.
     */
    public void show(Animation anim) {
        show(true, anim);
    }

    /**
     * Make the badge non-visible in the UI.
     * 
     */
    public void hide() {
        hide(false, null);
    }

    /**
     * Make the badge non-visible in the UI.
     * 
     * @param animate
     *            flag to apply the default fade-out animation.
     */
    public void hide(boolean animate) {
        hide(animate, fadeOut);
    }

    /**
     * Make the badge non-visible in the UI.
     * 
     * @param anim
     *            Animation to apply to the view when made non-visible.
     */
    public void hide(Animation anim) {
        hide(true, anim);
    }

    /**
     * Toggle the badge visibility in the UI.
     * 
     */
    public void toggle() {
        toggle(false, null, null);
    }

    /**
     * Toggle the badge visibility in the UI.
     * 
     * @param animate
     *            flag to apply the default fade-in/out animation.
     */
    public void toggle(boolean animate) {
        toggle(animate, fadeIn, fadeOut);
    }

    /**
     * Toggle the badge visibility in the UI.
     * 
     * @param animIn
     *            Animation to apply to the view when made visible.
     * @param animOut
     *            Animation to apply to the view when made non-visible.
     */
    public void toggle(Animation animIn, Animation animOut) {
        toggle(true, animIn, animOut);
    }

    private void show(boolean animate, Animation anim) {
        if (getBackground() == null) {
            if (badgeBg == null) {
                badgeBg = getDefaultBackground();
            }
            setBackgroundDrawable(badgeBg);
        }
        applyLayoutParams();

        if (animate) {
            this.startAnimation(anim);
        }
        this.setVisibility(View.VISIBLE);
        isShown = true;
    }

    private void hide(boolean animate, Animation anim) {
        this.setVisibility(View.GONE);
        if (animate) {
            this.startAnimation(anim);
        }
        isShown = false;
    }

    private void toggle(boolean animate, Animation animIn, Animation animOut) {
        if (isShown) {
            hide(animate && (animOut != null), animOut);
        } else {
            show(animate && (animIn != null), animIn);
        }
    }

    /**
     * Increment the numeric badge label. If the current badge label cannot be
     * converted to an integer value, its label will be set to "0".
     * 
     * @param offset
     *            the increment offset.
     */
    public int increment(int offset) {
        CharSequence txt = getText();
        int i;
        if (txt != null) {
            try {
                i = Integer.parseInt(txt.toString());
            } catch (NumberFormatException e) {
                i = 0;
            }
        } else {
            i = 0;
        }
        i = i + offset;
        setText(String.valueOf(i));
        return i;
    }

    /**
     * Decrement the numeric badge label. If the current badge label cannot be
     * converted to an integer value, its label will be set to "0".
     * 
     * @param offset
     *            the decrement offset.
     */
    public int decrement(int offset) {
        return increment(-offset);
    }

    private ShapeDrawable getDefaultBackground() {

        int r = dipToPixels(DEFAULT_CORNER_RADIUS_DIP);
        float[] outerR = new float[] { r, r, r, r, r, r, r, r };

        RoundRectShape rr = new RoundRectShape(outerR, null, null);
        ShapeDrawable drawable = new ShapeDrawable(rr);
        drawable.getPaint().setColor(badgeColor);

        return drawable;

    }

    private void applyLayoutParams() {

        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        switch (badgePosition) {
        case POSITION_TOP_LEFT:
            lp.gravity = Gravity.LEFT | Gravity.TOP;
            lp.setMargins(badgeMarginH, badgeMarginV, 0, 0);
            break;
        case POSITION_TOP_RIGHT:
            lp.gravity = Gravity.RIGHT | Gravity.TOP;
            lp.setMargins(0, badgeMarginV, badgeMarginH, 0);
            break;
        case POSITION_BOTTOM_LEFT:
            lp.gravity = Gravity.LEFT | Gravity.BOTTOM;
            lp.setMargins(badgeMarginH, 0, 0, badgeMarginV);
            break;
        case POSITION_BOTTOM_RIGHT:
            lp.gravity = Gravity.RIGHT | Gravity.BOTTOM;
            lp.setMargins(0, 0, badgeMarginH, badgeMarginV);
            break;
        case POSITION_CENTER:
            lp.gravity = Gravity.CENTER;
            lp.setMargins(0, 0, 0, 0);
            break;
        default:
            break;
        }

        setLayoutParams(lp);

    }

    /**
     * Returns the target View this badge has been attached to.
     * 
     */
    public View getTarget() {
        return target;
    }

    /**
     * Is this badge currently visible in the UI?
     * 
     */
    @Override
    public boolean isShown() {
        return isShown;
    }

    /**
     * Returns the positioning of this badge.
     * 
     * one of POSITION_TOP_LEFT, POSITION_TOP_RIGHT, POSITION_BOTTOM_LEFT,
     * POSITION_BOTTOM_RIGHT, POSTION_CENTER.
     * 
     */
    public int getBadgePosition() {
        return badgePosition;
    }

    /**
     * Set the positioning of this badge.
     * 
     * @param layoutPosition
     *            one of POSITION_TOP_LEFT, POSITION_TOP_RIGHT,
     *            POSITION_BOTTOM_LEFT, POSITION_BOTTOM_RIGHT, POSTION_CENTER.
     * 
     */
    public void setBadgePosition(int layoutPosition) {
        this.badgePosition = layoutPosition;
    }

    /**
     * Returns the horizontal margin from the target View that is applied to
     * this badge.
     * 
     */
    public int getHorizontalBadgeMargin() {
        return badgeMarginH;
    }

    /**
     * Returns the vertical margin from the target View that is applied to this
     * badge.
     * 
     */
    public int getVerticalBadgeMargin() {
        return badgeMarginV;
    }

    /**
     * Set the horizontal/vertical margin from the target View that is applied
     * to this badge.
     * 
     * @param badgeMargin
     *            the margin in pixels.
     */
    public void setBadgeMargin(int badgeMargin) {
        this.badgeMarginH = badgeMargin;
        this.badgeMarginV = badgeMargin;
    }

    /**
     * Set the horizontal/vertical margin from the target View that is applied
     * to this badge.
     * 
     * @param horizontal
     *            margin in pixels.
     * @param vertical
     *            margin in pixels.
     */
    public void setBadgeMargin(int horizontal, int vertical) {
        this.badgeMarginH = horizontal;
        this.badgeMarginV = vertical;
    }

    /**
     * Returns the color value of the badge background.
     * 
     */
    public int getBadgeBackgroundColor() {
        return badgeColor;
    }

    /**
     * Set the color value of the badge background.
     * 
     * @param badgeColor
     *            the badge background color.
     */
    public void setBadgeBackgroundColor(int badgeColor) {
        this.badgeColor = badgeColor;
        badgeBg = getDefaultBackground();
    }

    private int dipToPixels(int dip) {
        Resources r = getResources();
        float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip,
                r.getDisplayMetrics());
        return (int) px;
    }

}

2) Use this SlidingTabLayout instead of Original one:

/*
 * Copyright (C) 2013 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 viewbadger.demo;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Typeface;
import android.os.Build;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.TextView;

/**
 * To be used with ViewPager to provide a tab indicator component which give
 * constant feedback as to the user's scroll progress.
 * <p>
 * To use the component, simply add it to your view hierarchy. Then in your
 * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
 * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is
 * being used for.
 * <p>
 * The colors can be customized in two ways. The first and simplest is to
 * provide an array of colors via {@link #setSelectedIndicatorColors(int...)}
 * and {@link #setDividerColors(int...)}. The alternative is via the
 * {@link TabColorizer} interface which provides you complete control over which
 * color is used for any individual position.
 * <p>
 * The views used as tabs can be customized by calling
 * {@link #setCustomTabView(int, int)}, providing the layout ID of your custom
 * layout.
 */
public class SlidingTabLayout extends HorizontalScrollView {

    /**
     * Allows complete control over the colors drawn in the tab layout. Set with
     * {@link #setCustomTabColorizer(TabColorizer)}.
     */
    public interface TabColorizer {

        /**
         * @return return the color of the indicator used when {@code position}
         *         is selected.
         */
        int getIndicatorColor(int position);

        /**
         * @return return the color of the divider drawn to the right of
         *         {@code position}.
         */
        int getDividerColor(int position);

    }

    private static final int TITLE_OFFSET_DIPS = 24;
    private static final int TAB_VIEW_PADDING_DIPS = 16;
    private static final int TAB_VIEW_TEXT_SIZE_SP = 12;

    private int mTitleOffset;

    private int mTabViewLayoutId;
    private int mTabViewTextViewId;

    public SlidingTabStrip getTabStrip() {
        return mTabStrip;
    }

    private ViewPager mViewPager;
    private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;

    private final SlidingTabStrip mTabStrip;

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

    public SlidingTabLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

        // Disable the Scroll Bar
        setHorizontalScrollBarEnabled(false);
        // Make sure that the Tab Strips fills this View
        setFillViewport(true);

        mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources()
                .getDisplayMetrics().density);

        mTabStrip = new SlidingTabStrip(context);
        addView(mTabStrip, LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    }

    /**
     * Set the custom {@link TabColorizer} to be used.
     * 
     * If you only require simple custmisation then you can use
     * {@link #setSelectedIndicatorColors(int...)} and
     * {@link #setDividerColors(int...)} to achieve similar effects.
     */
    public void setCustomTabColorizer(TabColorizer tabColorizer) {
        mTabStrip.setCustomTabColorizer(tabColorizer);
    }

    /**
     * Sets the colors to be used for indicating the selected tab. These colors
     * are treated as a circular array. Providing one color will mean that all
     * tabs are indicated with the same color.
     */
    public void setSelectedIndicatorColors(int... colors) {
        mTabStrip.setSelectedIndicatorColors(colors);
    }

    /**
     * Sets the colors to be used for tab dividers. These colors are treated as
     * a circular array. Providing one color will mean that all tabs are
     * indicated with the same color.
     */
    public void setDividerColors(int... colors) {
        mTabStrip.setDividerColors(colors);
    }

    /**
     * Set the {@link ViewPager.OnPageChangeListener}. When using
     * {@link SlidingTabLayout} you are required to set any
     * {@link ViewPager.OnPageChangeListener} through this method. This is so
     * that the layout can update it's scroll position correctly.
     * 
     * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
     */
    public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
        mViewPagerPageChangeListener = listener;
    }

    /**
     * Set the custom layout to be inflated for the tab views.
     * 
     * @param layoutResId
     *            Layout id to be inflated
     * @param textViewId
     *            id of the {@link TextView} in the inflated view
     */
    public void setCustomTabView(int layoutResId, int textViewId) {
        mTabViewLayoutId = layoutResId;
        mTabViewTextViewId = textViewId;
    }

    /**
     * Sets the associated view pager. Note that the assumption here is that the
     * pager content (number of tabs and tab titles) does not change after this
     * call has been made.
     */
    public void setViewPager(ViewPager viewPager) {
        mTabStrip.removeAllViews();

        mViewPager = viewPager;
        if (viewPager != null) {
            viewPager.setOnPageChangeListener(new InternalViewPagerListener());
            populateTabStrip();
        }
    }

    /**
     * Create a default view to be used for tabs. This is called if a custom tab
     * view is not set via {@link #setCustomTabView(int, int)}.
     */
    @SuppressLint("NewApi")
    protected TextView createDefaultTabView(Context context) {
        TextView textView = new TextView(context);
        textView.setGravity(Gravity.CENTER);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
        textView.setTypeface(Typeface.DEFAULT_BOLD);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            // If we're running on Honeycomb or newer, then we can use the
            // Theme's
            // selectableItemBackground to ensure that the View has a pressed
            // state
            TypedValue outValue = new TypedValue();
            getContext().getTheme().resolveAttribute(
                    android.R.attr.selectableItemBackground, outValue, true);
            textView.setBackgroundResource(outValue.resourceId);
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            // If we're running on ICS or newer, enable all-caps to match the
            // Action Bar tab style
            textView.setAllCaps(true);
        }

        int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources()
                .getDisplayMetrics().density);
        textView.setPadding(padding, padding, padding, padding);

        return textView;
    }

    private void populateTabStrip() {
        final PagerAdapter adapter = mViewPager.getAdapter();
        final View.OnClickListener tabClickListener = new TabClickListener();

        for (int i = 0; i < adapter.getCount(); i++) {
            View tabView = null;
            TextView tabTitleView = null;

            if (mTabViewLayoutId != 0) {
                // If there is a custom tab view layout id set, try and inflate
                // it
                tabView = LayoutInflater.from(getContext()).inflate(
                        mTabViewLayoutId, mTabStrip, false);
                tabTitleView = (TextView) tabView
                        .findViewById(mTabViewTextViewId);
            }

            if (tabView == null) {
                tabView = createDefaultTabView(getContext());
            }

            if (tabTitleView == null && TextView.class.isInstance(tabView)) {
                tabTitleView = (TextView) tabView;
            }

            tabTitleView.setText(adapter.getPageTitle(i));
            // tabView.setOnClickListener(tabClickListener);

            final int index_i = i;

            tabView.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    mViewPager.setCurrentItem(index_i);
                }
            });

            mTabStrip.addView(tabView);
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();

        if (mViewPager != null) {
            scrollToTab(mViewPager.getCurrentItem(), 0);
        }
    }

    private void scrollToTab(int tabIndex, int positionOffset) {
        final int tabStripChildCount = mTabStrip.getChildCount();
        if (tabStripChildCount == 0 || tabIndex < 0
                || tabIndex >= tabStripChildCount) {
            return;
        }

        View selectedChild = mTabStrip.getChildAt(tabIndex);
        if (selectedChild != null) {
            int targetScrollX = selectedChild.getLeft() + positionOffset;

            if (tabIndex > 0 || positionOffset > 0) {
                // If we're not at the first child and are mid-scroll, make sure
                // we obey the offset
                targetScrollX -= mTitleOffset;
            }

            scrollTo(targetScrollX, 0);
        }
    }

    private class InternalViewPagerListener implements
            ViewPager.OnPageChangeListener {
        private int mScrollState;

        @Override
        public void onPageScrolled(int position, float positionOffset,
                int positionOffsetPixels) {
            int tabStripChildCount = mTabStrip.getChildCount();
            if ((tabStripChildCount == 0) || (position < 0)
                    || (position >= tabStripChildCount)) {
                return;
            }

            mTabStrip.onViewPagerPageChanged(position, positionOffset);

            View selectedTitle = mTabStrip.getChildAt(position);
            int extraOffset = (selectedTitle != null) ? (int) (positionOffset * selectedTitle
                    .getWidth()) : 0;
            scrollToTab(position, extraOffset);

            if (mViewPagerPageChangeListener != null) {
                mViewPagerPageChangeListener.onPageScrolled(position,
                        positionOffset, positionOffsetPixels);
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            mScrollState = state;

            if (mViewPagerPageChangeListener != null) {
                mViewPagerPageChangeListener.onPageScrollStateChanged(state);
            }
        }

        @Override
        public void onPageSelected(int position) {
            if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
                mTabStrip.onViewPagerPageChanged(position, 0f);
                scrollToTab(position, 0);
            }

            if (mViewPagerPageChangeListener != null) {
                mViewPagerPageChangeListener.onPageSelected(position);
            }
        }

    }

    private class TabClickListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            Log.e("tab click listener", "" + v + " : unmatched");
            for (int i = 0; i < mTabStrip.getChildCount(); i++) {
                View vv = mTabStrip.getChildAt(i);
                if (vv instanceof FrameLayout) {
                    Log.e("frameLayout", "framelayout");
                    Log.e("" + v, "" + vv);
                }
                if (v == vv) {
                    mViewPager.setCurrentItem(i);
                    Log.e("tab click listener", "" + v + " : matched pos : "
                            + i);
                    return;
                }
            }
        }
    }

}

3) FragmentA button click listener code :

    Button b1 = (Button) fragmentView
            .findViewById(R.id.tab1_button_fragmenta);
    b1.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {

            badge = new BadgeView(getActivity(),
                    ((DemoActivity) getActivity()).mSlidingTabLayout
                            .getTabStrip(), 0);
            badge.setText("1");

            badge.toggle();
        }
    });

    Button b2 = (Button) fragmentView
            .findViewById(R.id.tab1_button_fragmentb);
    b2.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {

            BadgeView badge = new BadgeView(getActivity(),
                    ((DemoActivity) getActivity()).mSlidingTabLayout
                            .getTabStrip(), 1);
            badge.setText("2");

            badge.toggle();
        }
    });

And You are Done. :)


Now Reasoning:

The problem is that ViewBadger Removes the original View and adds Framelayout and that removed view after dynamically adding a textView. is That matters?

Yes: because You are using SlidingTabLayout. In which onTabClickListener Class is used, which checks that if a view is of type TextView. See this code below, Before adding the badview it will always show the textview, but after that it will show framelayout for badgedview.

    private class TabClickListener implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            Log.e("tab click listener", "" + v + " : unmatched");
            for (int i = 0; i < mTabStrip.getChildCount(); i++) {
                View vv = mTabStrip.getChildAt(i);

                // I have added these lines for debugging
                if (vv instanceof FrameLayout) {
                    Log.e("frameLayout", "framelayout");
                }
                else if (vv instanceof TextView) {
                    Log.e("textview", "textview");
                }

                // Original Code
                if (v == mTabStrip.getChildAt(i)) {
                    mViewPager.setCurrentItem(i);
                    Log.e("tab click listener", "" + v + " : matched pos : "
                            + i);
                    return;
                }
            }
        }
    }

So I replaced that clickListener Class and Used this code :

        final int index_i = i;

        tabView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                mViewPager.setCurrentItem(index_i);
            }
        });

which does not see that whether it is textView of FrameLayout or whatever, just load the item at ith Index. :)

Cheers -Nadeem Iqbal



来源:https://stackoverflow.com/questions/25584010/badgeview-and-slidingtabstrip-clicking-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!