1

我正在使用来自以下位置的滑动标签:

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

和 BadgeView 来自:

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

我只是添加这些代码行SlidingTabLayout来访问每个选项卡:

    public SlidingTabStrip getTabStrip() {
    return mTabStrip;
}

所以在fragmenta中我可以使用下面的代码将badgeview添加到每个选项卡:

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;
    }

和片段布局:

<?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>

结果是:

在此处输入图像描述

但是在我添加 BadgeView 之后,单击选项卡的功能就消失了。所以我不能点击标签导航到其他页面。谁能帮我做什么?

对于那些只想专注于解决方案而不浪费时间创建项目的人来说,这是主要活动:-)

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);
    }
}

}

和活动主:

<?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>
4

1 回答 1

2

首先:

代码:

1) 使用此 BadgeView 类而不是 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)使用这个 SlidingTabLayout 而不是原来的一个:

/*
 * 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 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();
        }
    });

你完成了。:)


现在推理:

问题是 ViewBadger 删除了原始视图并添加了 Framelayout 以及动态添加 textView 后删除的视图。这很重要吗?

是的:因为您使用的是 SlidingTabLayout。其中使用了 onTabClickListener 类,它检查视图是否为 TextView 类型。请参阅下面的代码,在添加 badview 之前,它将始终显示 textview,但之后将显示 badview 的 framelayout。

    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;
                }
            }
        }
    }

所以我替换了那个 clickListener 类并使用了这个代码:

        final int index_i = i;

        tabView.setOnClickListener(new OnClickListener() {

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

它看不到它是 FrameLayout 的 textView 还是其他什么,只需在第 i 个索引处加载项目。:)

干杯 -纳迪姆·伊克巴尔

于 2014-09-10T04:31:40.817 回答