分享好友 移动开发首页 频道列表

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

Android开发  2016-11-16 10:040

没什么说的,就是一个代码整理。

先来看一下效果图:

标题少的:

标题多的:

因为最近两个项目都有类似效果,所以这里整理了一下代码。实现代码借鉴了 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下载

查看更多关于【Android开发】的文章

展开全文
相关推荐
反对 0
举报 0
评论 0
图文资讯
热门推荐
优选好物
更多热点专题
更多推荐文章
Supporting Multiple Screens
术语和概念Screen size 屏幕尺寸又称「屏幕大小」,是屏幕对角线的物理尺寸。单位英寸 inch,比如 Samsung Note4 是 5.7 英寸。Resolution 屏幕分辨率屏幕纵横方向上物理像素的总数,比如 Samsung Note4 是 2560x1440,表示纵向有 2560 个像素,横向有 1440

0评论2017-02-05363

Android插件化(4):OpenAtlasの插件的卸载与更新
如果看过我的前两篇博客Android插件化(2):OpenAtlas插件安装过程分析和Android插件化(3):OpenAtlas的插件重建以及使用时安装,就知道在插件的安装过程中OpenAtlas做了哪些事,那么插件的卸载就只需要把持久化和内存中的内容移除即可。1.插件的卸载插件卸载的

0评论2017-02-05229

个人简历
吴朝晖/男/1993.1本科/南京师范大学中北学院信息系工作年限:1年以内技术博客:wuzhaohui026.github.ioGitHub:https://github.com/wuzhaohui026期望职位:Android开发(初级Android工程师)期望薪资:税前月薪5.5k~7k期望城市:常州工作经历常州慧展信息科技有

0评论2017-02-05126

Android插件化(五):OpenAtlasの四大组件的Hack
引言到目前为止,我们已经分析了OpenAtlas中插件的安装,卸载,更新,以及安装好插件之后组件类的加载过程,但是对于这些是如何引发的还不知道,比如,在宿主的一个Activit中调用startActivity()跳转到插件中的一个Activity,如何判断这个Activity在的插件是否

0评论2017-02-0598

更多推荐