美文网首页
封装一个可滑动的底部导航TabLayoutView

封装一个可滑动的底部导航TabLayoutView

作者: 一克拉战英 | 来源:发表于2017-05-18 14:53 被阅读0次

    首先我们先看下封装的基础类TabLayoutView.java类

    public class TabLayoutView extends LinearLayout {
    
        private Context context;
        private String[] titles; //要显示的标题
        private int[] imgs; //图标
        private int[] imgsSelected; //图标
    
        private int imgwidth;
        private int imgheight;
        private int txtsize; //标题大小
        private int txtColor; //标题未选中颜色
        private int txtSelectedColor; //选择颜色
    
        private List<TextView> textViews; //保存标题
        private List<ImageView> imageViews; //保存图片
        private List<TextView> tvDots;//保存圆点
        private List<ImageView> tvImgs;//保存小红点
        private int currentIndex = 0;
    
        private OnItemOnclickListener onItemOnclickListener;
    
        public TabLayoutView(Context context) {
            this(context, null);
        }
    
        public TabLayoutView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public TabLayoutView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            this.context = context;
        }
    
        public void setOnItemOnclickListener(OnItemOnclickListener onItemOnclickListener) {
            this.onItemOnclickListener = onItemOnclickListener;
        }
    
        /**
         * 设置标题、图片和当前选中的条目
         *
         * @param tabtxts
         * @param imgs
         * @param currentIndex
         */
        public void setDataSource(String[] tabtxts, int[] imgs, int[] imgsSelected, int currentIndex) {
            this.titles = tabtxts;
            this.imgs = imgs;
            this.currentIndex = currentIndex;
            this.imgsSelected = imgsSelected;
        }
    
        /**
         * 设置图标大小
         *
         * @param imgwidth  图标的宽度
         * @param imgheight 图标的高度
         */
        public void setImageStyle(int imgwidth, int imgheight) {
            this.imgwidth = dip2px(context, imgwidth);
            this.imgheight = dip2px(context, imgheight);
        }
    
        /**
         * 设置标题颜色
         *
         * @param txtsize          文字大小
         * @param txtColor         文字未选中颜色
         * @param txtSelectedColor 文字选中时颜色
         */
        public void setTextStyle(int txtsize, int txtColor, int txtSelectedColor) {
            this.txtsize = txtsize;
            this.txtColor = txtColor;
            this.txtSelectedColor = txtSelectedColor;
        }
    
        /**
         * 动态布局
         * 1、外层为横向线下布局
         * 2、动态添加相对布局,平分父布局,使宽度一致,添加到横向布局中
         * 3、总线布局添加图标和标题,并添加到相对布局中
         * 4、添加圆点到相对布局中,并设置在3的右上角
         */
        public void initDatas() {
            textViews = new ArrayList<>();
            imageViews = new ArrayList<>();
            tvDots = new ArrayList<>();
            tvImgs = new ArrayList<>();
    
            setOrientation(HORIZONTAL);
            LayoutParams lp = new LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT);
            lp.weight = 1;
            lp.gravity = Gravity.CENTER;
    
            LayoutParams imglp = new LayoutParams(imgwidth, imgheight);
            imglp.gravity = Gravity.CENTER;
    
            LayoutParams txtlp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            txtlp.gravity = Gravity.CENTER;
    
            RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            rlp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
    
            int size = titles.length;
            for (int i = 0; i < size; i++) {
                ImageView imageView = new ImageView(context);
                imageView.setLayoutParams(imglp);
                imageView.setScaleType(ImageView.ScaleType.FIT_XY);
    
                TextView textView = new TextView(context);
                textView.setText(titles[i]);
                textView.setLayoutParams(txtlp);
                textView.setTextSize(txtsize);
    
                LinearLayout cly = new LinearLayout(context);
                cly.setId(i + 100);
                cly.setGravity(Gravity.CENTER);
                cly.setOrientation(VERTICAL);
                cly.setLayoutParams(imglp);
                cly.addView(imageView);
    
                RelativeLayout prl = new RelativeLayout(context);
    
                RelativeLayout.LayoutParams rlDot = new RelativeLayout.LayoutParams(dip2px(context, 12), dip2px(context, 12));
                rlDot.addRule(RelativeLayout.RIGHT_OF, cly.getId());
                rlDot.addRule(RelativeLayout.ABOVE, cly.getId());
                rlDot.setMargins(-dip2px(context, 10), 0, 0, -dip2px(context, 10));
    
                TextView tvDot = new TextView(context);
    
                tvDot.setText("0");
                tvDot.setTextSize(10);
                tvDot.setGravity(Gravity.CENTER);
                tvDot.setVisibility(GONE);
                tvDot.setTextColor(context.getResources().getColor(R.color.white));
                tvDot.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.circle_dot_red_bg));
    
                RelativeLayout.LayoutParams rlimgDot = new RelativeLayout.LayoutParams(dip2px(context, 8), dip2px(context, 8));
                rlimgDot.addRule(RelativeLayout.RIGHT_OF, cly.getId());
                rlimgDot.addRule(RelativeLayout.ABOVE, cly.getId());
                rlimgDot.setMargins(-dip2px(context, 5), 0, 0, -dip2px(context, 5));
                ImageView imgDot = new ImageView(context);
                imgDot.setImageResource(R.drawable.circle_dot_red_bg);
                imgDot.setVisibility(GONE);
    
    
                final int index = i;
                prl.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        setSelectStyle(index);
                        if (onItemOnclickListener != null) {
                            onItemOnclickListener.onItemClick(index);
                        }
                    }
                });
    
                cly.addView(textView);
                prl.addView(cly, rlp);
                prl.addView(tvDot, rlDot);
                prl.addView(imgDot, rlimgDot);
                addView(prl, lp);
    
                textViews.add(textView);
                imageViews.add(imageView);
                tvDots.add(tvDot);
                tvImgs.add(imgDot);
            }
            setSelectStyle(currentIndex);
        }
    
        public void setSelectStyle(int index) {
            int size = titles.length;
            for (int i = 0; i < size; i++) {
                if (i == index) {
                    textViews.get(i).setTextColor(context.getResources().getColor(txtSelectedColor));
                    imageViews.get(i).setSelected(true);
                    imageViews.get(i).setImageResource(imgsSelected[i]);
    
                } else {
                    textViews.get(i).setTextColor(context.getResources().getColor(txtColor));
                    imageViews.get(i).setSelected(false);
                    imageViews.get(i).setImageResource(imgs[i]);
    
                }
            }
        }
    
        /**
         * 设置圆点
         *
         * @param index 圆点索引
         * @param count 圆点个数
         */
        public void setDotsCount(int index, int count) {
            if (tvDots == null || index > tvDots.size() - 1)
                return;
            if (count > 0) {
                tvDots.get(index).setVisibility(VISIBLE);
                tvDots.get(index).setText(count + "");
                tvImgs.get(index).setVisibility(GONE);
            } else if (count == -1) {
                tvDots.get(index).setVisibility(GONE);
                tvImgs.get(index).setVisibility(VISIBLE);
            } else {
                tvDots.get(index).setVisibility(GONE);
                tvImgs.get(index).setVisibility(GONE);
            }
        }
    
        public interface OnItemOnclickListener {
            void onItemClick(int index);
        }
    
        private int sp2px(Context context, float spValue) {
            final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
            return (int) (spValue * fontScale + 0.5f);
        }
    
        private int dip2px(Context context, float dipValue) {
            final float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dipValue * scale + 0.5f);
        }
    }
    

    我们再来看一下Activity对应的xml文件

    <?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="@color/bg">
    
        <cn.hejia.jiapu.utils.NoScrollViewPager
            android:id="@+id/main_viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/main_tabview"
            android:overScrollMode="never" />
    
        <cn.hejia.jiapu.main.TabLayoutView
            android:id="@+id/main_tabview"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_alignParentBottom="true" />
    
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:layout_above="@+id/main_tabview"
            android:background="@color/lineColor" />
    </RelativeLayout>
    

    这里由于项目需求,我使用的是不可滑动的NoScrollViewPager,代码如下:

    /**
     * 不可以滑动,但是可以setCurrentItem的ViewPager。
     */
    
    public class NoScrollViewPager extends ViewPager {
        public NoScrollViewPager(Context context) {
            super(context);
        }
    
        public NoScrollViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent arg0) {
            return false;
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent arg0) {
            return false;
        }
    }
    

    如果你希望可以滑动切换,直接用ViewPager就可以了。
    然后我们直接需要导航的Activity中使用

    public class MainActivity extends AppCompatActivity {
    
        private ViewPager viewPager;
        private TabLayoutView tabLayoutView;
        private String[] titles = {"附近", "动态", "消息", "发现", "我的"};
        private int[] imgs = {R.mipmap.icon_nearby, R.mipmap.icon_circle, R.mipmap.icon_message, R.mipmap.icon_find, R.mipmap.icon_me};
        private int[] imgsselect = {R.mipmap.icon_nearby_selected, R.mipmap.icon_circle_selected, R.mipmap.icon_message_selected, R.mipmap.icon_find_selected, R.mipmap.icon_me_selected};
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            viewPager = (ViewPager) findViewById(R.id.viewpager);
            tabLayoutView = (TabLayoutView) findViewById(R.id.tabview);
            initFragments();
            tabLayoutView.setDataSource(titles, imgs,imgsselect,0);
            tabLayoutView.setImageStyle(25, 25);
            tabLayoutView.setTextStyle(12, R.color.color_999999,R.color.color_ff78a3);
            tabLayoutView.initDatas();
            setDots();
            tabLayoutView.setOnItemOnclickListener(new TabLayoutView.OnItemOnclickListener() {
                @Override
                public void onItemClick(int index) {
                    viewPager.setCurrentItem(index, true);
                }
            });
    
            viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                }
    
                @Override
                public void onPageSelected(int position) {
                    viewPager.setCurrentItem(position, false);
                    tabLayoutView.setSelectStyle(position);
                }
    
                @Override
                public void onPageScrollStateChanged(int state) {
    
                }
            });
    
    
        }
        
        private void initFragments()
        {
            List<Fragment> fragmentPages = new ArrayList<>();
            fragmentPages.add(new FragmentPage());
            fragmentPages.add(new FragmentPage());
            fragmentPages.add(new FragmentPage());
            fragmentPages.add(new FragmentPage());
            fragmentPages.add(new FragmentPage());
            ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), fragmentPages);
            viewPager.setAdapter(viewPagerAdapter);
        }
        /**
         * 设置底部右上角数字,0不显示(默认),>0实现数字,-1显示小红点
         */
        public void setDots()
        {
            tabLayoutView.setDotsCount(0, 1);
            tabLayoutView.setDotsCount(1, 0);
            tabLayoutView.setDotsCount(2, 3);
            tabLayoutView.setDotsCount(3, 0);
            tabLayoutView.setDotsCount(4, 5);
        }
    

    由于我们使用了ViewPager,所以我们要给其对应的Adapter

    public class ViewPagerAdapter extends FragmentPagerAdapter {
    
        private List<Fragment> fragments;
    
        public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments) {
            super(fm);
            this.fragments = fragments;
        }
    
        @Override
        public int getCount() {
            return fragments.size();
        }
    
        @Override
        public Fragment getItem(int position) {
            return fragments.get(position);
        }
    }
    

    最后附上用到的小红点的资源文件circle_dot_red_bg.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape
        xmlns:android= "http://schemas.android.com/apk/res/android"
        android:shape= "oval"
        android:useLevel= "false" >
        <solid android:color= "@color/red" />
        <stroke android:color="@color/red" android:width="2dp"/>
    </shape>
    

    到此我们就大功告成了,上面写的比较详细,大家可以根据具体需求自取。最后附上效果图

    231.png

    相关文章

      网友评论

          本文标题:封装一个可滑动的底部导航TabLayoutView

          本文链接:https://www.haomeiwen.com/subject/lgysxxtx.html