一个比较简陋的动态标题栏

博客主要介绍了如何在Android中实现动态标题栏,代码基于PagerSlidingTabStrip进行简化,包括标题少和多的情况。提供了效果图及主要实现代码,方便日后复用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

没什么说的,就是一个代码整理。
先来看一下效果图:
标题少的
这里写图片描述

标题多的
这里写图片描述

因为最近两个项目都有类似效果,所以这里整理了一下代码。实现代码借鉴了 PagerSlidingTabStrip.

比较简单,所以这里就直接贴出了主要的实现代码:

public class HorizontalView extends HorizontalScrollView {

    private LinearLayout container;
    private int tabPadding = 8;
    private int tabTextSize = 16;
    private int tabSelTextSize = 16;
    private int tabTextColor;
    private int count;

    private int screenWidth; // 屏幕宽度
    private int childViewWidth; // 控件宽度
    private LinearLayout.LayoutParams matchParams, weightParmas;

    private List<String> strList;
    private int selPos = 0;
    private Context context;

    public interface onItemClickListener {
        void onClick(int position);
    }

    private onItemClickListener listener;
//    private static final int[] ATTRS = new int[]{
//            android.R.attr.textSize,
//            android.R.attr.textColor
//    };

    public HorizontalView(Context context, AttributeSet attrs) {
        super(context, attrs);
        /**
         *当你想让一个高度值不足scrollview的子控件fillparent的时候,
         * 单独的定义android:layout_height="fill_parent"是不起作用的,
         * 必须加上fillviewport属性,当子控件的高度值大于scrollview的高度时,这个标签就没有任何意义了。
         */
        setFillViewport(true);
        setHorizontalScrollBarEnabled(false);
        this.context = context;

        container = new LinearLayout(getContext());
        container.setOrientation(LinearLayout.HORIZONTAL);
        container.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        addView(container);
        DisplayMetrics dm = getResources().getDisplayMetrics();
        screenWidth = dm.widthPixels;
        int paddingLeft = getPaddingLeft();
        int paddingRight = getPaddingRight();
        screenWidth = screenWidth - paddingLeft - paddingRight;
        // 把指定单位转换成像素。
        tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
        tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);
        tabSelTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabSelTextSize, dm);

        // get system attrs (android:textSize and android:textColor)
//        TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);
//
//        tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
//        tabTextColor = a.getColor(1, tabTextColor);
//
//        a.recycle();

        matchParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT);
        weightParmas = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);

    }


    public void setStrList(List<String> list) {
        strList = list;

        if (list == null || list.size() <= 0) {
            throw new IllegalStateException("There is no data in the title list ");
        }

        notifyDataSetChanged();

    }

    public void setItemClickListener(onItemClickListener listener) {
        this.listener = listener;
    }

    public void notifyDataSetChanged() {
        container.removeAllViews();
        count = strList.size();
        childViewWidth = 0;

        for (int i = 0; i < count; i++) {
            addTextTab(i, strList.get(i));
        }

        updateViewStyle();
    }

    public void addTextTab(final int position, String title) {
        final HorizontalViewItem view = new HorizontalViewItem(context);
        view.setFocusable(true);
        view.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (childViewWidth > screenWidth) {
                    int width = view.getWidth();
                    int left = view.getLeft();  // textview 左边位置
                    int tvMargin = screenWidth / 2 - width / 2;    // TextView的目标位置

                    if (left < tvMargin) {
                        scrollTo(0, 0);
                    } else {
                        scrollTo(left - tvMargin, 0);
                    }
                }
                selPos = position;
                updateViewStyle();
                if (listener != null) {
                    listener.onClick(position);
                }
//                Log.i("lfq", "textView scroll x  " + getScrollX() + ",  getleft " + textView.getLeft() + " , getRight " + textView.getRight() + " , textView width " + textView.getWidth() + " , totalWidth : " + childViewWidth);
            }
        });
        view.setPadding(tabPadding, 0, tabPadding, 0);
        view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
//                Log.i("lfq", position + " inside width : " + textView.getWidth());
                childViewWidth += view.getWidth();
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                    getViewTreeObserver().removeGlobalOnLayoutListener(
                            this);
                } else {
                    getViewTreeObserver().removeOnGlobalLayoutListener(
                            this);
                }
            }
        });
        view.setText(title);
//        container.addView(view, position, weightParmas);
        container.addView(view);
    }


    public void updateViewStyle() {
        for (int i = 0; i < count; i++) {
            View v = container.getChildAt(i);
            if (v instanceof HorizontalViewItem) {
                HorizontalViewItem tab = (HorizontalViewItem) v;
                tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);
                tab.setTypeface(null, Typeface.BOLD);
                tab.setTextColor(getResources().getColor(R.color.white_b0));
                tab.setLineColor(getResources().getColor(R.color.c_ff7a7a));
                // setAllCaps() is only available from API 14, so the upper case is made manually if we are on a
                // pre-ICS-build
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                    tab.setAllCaps(true);
                } else {
                    tab.setText(tab.getText().toString());
                }
                if (selPos == i) {
                    tab.setTextColor(Color.WHITE);
                    tab.setLineColor(Color.WHITE);
                    tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabSelTextSize);
                }
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int myWidth = getMeasuredWidth();
        int childWidth = 0;
        for (int i = 0; i < count; i++) {
            childWidth += container.getChildAt(i).getMeasuredWidth();
        }

        if (childWidth > 0 && myWidth > 0) {
            LinearLayout.LayoutParams params;
            if (childWidth <= myWidth) {
                params = weightParmas;
            } else {
                params = matchParams;
            }
            for (int i = 0; i < count; i++) {
                container.getChildAt(i).setLayoutParams(params);
            }
        }

    }
}

HorizontalViewItem 是一个通过布局文件自定义的 View , 就是标题里面所需的一个文本,一条线。

<?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:gravity="center"
              android:orientation="vertical">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:maxLines="1"
            android:textColor="#b0ffffff"
            android:textSize="14sp"/>

        <TextView
            android:id="@+id/tv_tip"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_marginTop="1dp"
            android:background="@android:color/white"/>
    </LinearLayout>

</LinearLayout>

代码也就这些,没什么技术含量,便于以后再次使用,所以在这里整理一份。

Demo下载

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值