1. 程式人生 > >Android快速開發02之仿京東底部Tab

Android快速開發02之仿京東底部Tab

自上一篇介紹了Android快速開發之封裝標題欄效果是顯而易見的。接下來我們對底部Tab也進行封裝。

效果:
這裡寫圖片描述 這裡寫圖片描述

然而實現的程式碼也就這麼幾行:

public class MainActivity extends BottomTabBaseActivity {

    @Override
    protected List<BottomTabView.TabItemView> getTabViews() {
        List<BottomTabView.TabItemView> tabItemViews = new ArrayList<>();
tabItemViews.add(new BottomTabView.TabItemView(this,"首頁",R.color.bottom_text_nor, R.color.bottom_text_pre,R.drawable.ic_home_norl,R.drawable.ic_home_pre)); tabItemViews.add(new BottomTabView.TabItemView(this,"分類",R.color.bottom_text_nor, R.color.bottom
_text_pre,R.drawable.ic_classify_nor,R.drawable.ic_classify_pre)); tabItemViews.add(new BottomTabView.TabItemView(this,"發現",R.color.bottom_text_nor, R.color.bottom_text_pre,R.drawable.ic_find_nor,R.drawable.ic_find_pre)); /*tabItemViews.add(new BottomTabView.TabItemView(this,"購物車",R.color.bottom_text_nor, R.color.bottom_text_pre,R.drawable.ic_car_nor,R.drawable.ic_car_pre));*/
tabItemViews.add(new BottomTabView.TabItemView(this,"我的",R.color.bottom_text_nor, R.color.bottom_text_pre,R.drawable.ic_mine_noe,R.drawable.ic_mine_pre)); return tabItemViews; } @Override protected List<Fragment> getFragments() { List<Fragment> fragments = new ArrayList<>(); fragments.add(new HomeFragment()); fragments.add(new ClassifyFragment()); fragments.add(new FindFragment()); /*fragments.add(new ShopCarFragment());*/ fragments.add(new MineFragment()); return fragments; } }

新增 CenterView 也很簡單,只需重寫 getCenterView 方法並返回你想新增的 View。

@Override
protected View getCenterView() {
    ImageView centerView = new ImageView(this);
    centerView.setImageResource(R.mipmap.ic_launcher_round);
    centerView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Toast.makeText(MainActivity.this,"中間圖示被點選了",Toast.LENGTH_SHORT).show();
            }
        });
    return centerView;
    }

1,底部的BottomTabView.java

package com.gyq.topbarfast.view;

import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.gyq.topbarfast.R;

import java.util.List;

/**
 * Created by gyq on 2017/5/18 10:24
 */
public class BottomTabView extends LinearLayout {
    /**
     * 記錄最新的選擇位置
     */
    private int lastPosition = -1;

    /**
     * 所有 TabItem 的集合
     */
    private List<TabItemView> tabItemViews;

    public BottomTabView(Context context) {
        super(context);
    }

    public BottomTabView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }


    public BottomTabView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 連線 Viewpager
     * @param viewPager 
     */
    public void setUpWithViewPager(final ViewPager viewPager){
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                updatePosition(position);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        setOnTabItemSelectListener(new OnTabItemSelectListener() {
            @Override
            public void onTabItemSelect(int position) {
                viewPager.setCurrentItem(position);
            }
        });
    }

    /**
     * 設定 Tab Item View
     */
    public void setTabItemViews(List<TabItemView> tabItemViews){
        setTabItemViews(tabItemViews, null);
    }

    /**
     * 設定 Tab Item View
     */
    public void setTabItemViews(List<TabItemView> tabItemViews, View centerView){

        if (this.tabItemViews != null){
            throw new RuntimeException("不能重複設定!");
        }

        if (tabItemViews == null || tabItemViews.size() < 2){
            throw new RuntimeException("TabItemView 的數量必須大於2!");
        }

        this.tabItemViews = tabItemViews;
        for (int i=0; i<tabItemViews.size(); i++) {

            if (centerView != null && i == tabItemViews.size() / 2){
                this.addView(centerView);
            }

            final TabItemView tabItemView = tabItemViews.get(i);

            this.addView(tabItemView);

            final int finalI = i;

            tabItemView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {

                    if (finalI == lastPosition){
                        // 第二次點選
                        if (onSecondSelectListener != null){
                            onSecondSelectListener.onSecondSelect(finalI);
                        }
                        return ;
                    }

                    updatePosition(finalI);

                    if (onTabItemSelectListener != null){
                        onTabItemSelectListener.onTabItemSelect(finalI);
                    }
                }
            });
        }

        /**
         * 將所有的 TabItem 設定為 初始化狀態
         */
        for (TabItemView tab : tabItemViews) {
            tab.setStatus(TabItemView.DEFAULT);
        }

        /**
         * 預設狀態選擇第一個
         */
        updatePosition(0);
    }

    /**
     * 更新被選中 Tab Item 的狀態
     * 恢復上一個 Tab Item 的狀態
     */
    public void updatePosition(int position){
        if (lastPosition != position){
            if (tabItemViews != null && tabItemViews.size() != 0){
                tabItemViews.get(position).setStatus(TabItemView.PRESS);
                if (lastPosition != -1) {
                    tabItemViews.get(lastPosition).setStatus(TabItemView.DEFAULT);
                }
                lastPosition = position;
            }else{
                throw new RuntimeException("please setTabItemViews !");
            }
        }
    }

    OnTabItemSelectListener onTabItemSelectListener;
    OnSecondSelectListener onSecondSelectListener;

    public void setOnTabItemSelectListener(OnTabItemSelectListener onTabItemSelectListener){
        this.onTabItemSelectListener = onTabItemSelectListener;
    }

    public void setOnSecondSelectListener(OnSecondSelectListener onSecondSelectListener){
        this.onSecondSelectListener = onSecondSelectListener;
    }

    /**
     * 第二次被選擇的監聽器
     */
    public interface OnSecondSelectListener{
        void onSecondSelect(int position);
    }

    /**
     * 第一次被選擇的監聽器
     */
    public interface OnTabItemSelectListener{
        void onTabItemSelect(int position);
    }

    /**
     * Item
     */
    public static class TabItemView extends LinearLayout{

        /**
         * 兩個狀態 選中、未選中
         */
        public final static int PRESS = 1;
        public final static int DEFAULT = 2;

        /**
         * Item 的標題
         */
        public String title;

        /**
         * 標題的兩個狀態的顏色 選中、未選中
         */
        public int colorDef;
        public int colorPress;

        /**
         * 兩個圖示的 資源 id ,選中、未選中
         */
        public int iconResDef;
        public int iconResPress;

        public TextView tvTitle;
        public ImageView ivIcon;

        public TabItemView(Context context, String title, int colorDef, int colorPress,
                           int iconResDef, int iconResPress) {
            super(context);
            this.title = title;
            this.colorDef = colorDef;
            this.colorPress = colorPress;
            this.iconResDef = iconResDef;
            this.iconResPress = iconResPress;
            init();
        }

        /**
         * 初始化
         */
        public void init(){
            View view = LayoutInflater.from(super.getContext()).inflate(R.layout.view_tab_item, this);
            tvTitle = (TextView) view.findViewById(R.id.tvTitle);
            ivIcon = (ImageView) view.findViewById(R.id.ivIcon);

            LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            layoutParams.weight = 1;
            view.setLayoutParams(layoutParams);

            tvTitle.setText(title);

        }

        /**
         * 設定狀態
         */
        public void setStatus(int status){
            tvTitle.setTextColor(ContextCompat.getColor(super.getContext(), status == PRESS ? colorPress : colorDef));
            ivIcon.setImageResource(status == PRESS ? iconResPress : iconResDef);
        }
    }
}

2,view_tab_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/viewTabView"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:background="?android:selectableItemBackground"
    android:gravity="center"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/ivIcon"
        android:layout_weight="1"
        android:src="@mipmap/ic_launcher_round"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TextView
        android:id="@+id/tvTitle"
        android:layout_weight="1"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="標題"/>

</LinearLayout>

3,BottomTabBaseActivity.java

package com.gyq.topbarfast;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import com.gyq.topbarfast.view.BottomTabView;

import java.util.List;

public abstract class BottomTabBaseActivity extends AppCompatActivity {
    private BottomTabView bottomTabView;
    private FragmentPagerAdapter mAdapter;
    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bottom_tab_base);

        bottomTabView = (BottomTabView)findViewById(R.id.bottom_tab_view);
        mViewPager = (ViewPager)findViewById(R.id.viewPager);

        if (getCenterView() == null) {
            bottomTabView.setTabItemViews(getTabViews());
        }else {
            bottomTabView.setTabItemViews(getTabViews(),getCenterView());
        }

        mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
                return getFragments().get(position);
            }

            @Override
            public int getCount() {
                return getFragments().size();
            }
        };

        mViewPager.setAdapter(mAdapter);

        bottomTabView.setOnTabItemSelectListener(new BottomTabView.OnTabItemSelectListener() {
            @Override
            public void onTabItemSelect(int position) {
                mViewPager.setCurrentItem(position,true);
            }
        });

        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                bottomTabView.updatePosition(position);   //bottomtab同步切換選中位置
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

    }

    protected abstract List<BottomTabView.TabItemView> getTabViews();

    protected abstract List<Fragment> getFragments();

    protected View getCenterView() {
        return null;
    }
}

5,activity_bottom_tab_base.xml佈局檔案:

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

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="0.1dp"
        android:background="#c7c7c7"/>

    <com.gyq.topbarfast.view.BottomTabView
        android:id="@+id/bottom_tab_view"
        android:background="@color/bottom_bg"
        android:gravity="bottom"
        android:layout_width="match_parent"
        android:layout_height="50dp"/>

</LinearLayout>

6,MainActivity.java

package com.gyq.topbarfast;

import android.support.v4.app.Fragment;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.gyq.topbarfast.fragment.ClassifyFragment;
import com.gyq.topbarfast.fragment.FindFragment;
import com.gyq.topbarfast.fragment.HomeFragment;
import com.gyq.topbarfast.fragment.MineFragment;
import com.gyq.topbarfast.view.BottomTabView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends BottomTabBaseActivity {

    @Override
    protected List<BottomTabView.TabItemView> getTabViews() {
        List<BottomTabView.TabItemView> tabItemViews = new ArrayList<>();
        tabItemViews.add(new BottomTabView.TabItemView(this,"首頁",R.color.bottom_text_nor,
                R.color.bottom_text_pre,R.drawable.ic_home_norl,R.drawable.ic_home_pre));
        tabItemViews.add(new BottomTabView.TabItemView(this,"分類",R.color.bottom_text_nor,
                R.color.bottom_text_pre,R.drawable.ic_classify_nor,R.drawable.ic_classify_pre));
        tabItemViews.add(new BottomTabView.TabItemView(this,"發現",R.color.bottom_text_nor,
                R.color.bottom_text_pre,R.drawable.ic_find_nor,R.drawable.ic_find_pre));
         //第二效果
        /*tabItemViews.add(new BottomTabView.TabItemView(this,"購物車",R.color.bottom_text_nor,
                R.color.bottom_text_pre,R.drawable.ic_car_nor,R.drawable.ic_car_pre));*/
        tabItemViews.add(new BottomTabView.TabItemView(this,"我的",R.color.bottom_text_nor,
                R.color.bottom_text_pre,R.drawable.ic_mine_noe,R.drawable.ic_mine_pre));
        return tabItemViews;
    }

    @Override
    protected List<Fragment> getFragments() {
        List<Fragment> fragments = new ArrayList<>();
        fragments.add(new HomeFragment());
        fragments.add(new ClassifyFragment());
        fragments.add(new FindFragment());
        //第二效果
        /*fragments.add(new ShopCarFragment());*/
        fragments.add(new MineFragment());
        return fragments;
    }

    @Override
    protected View getCenterView() {
        //較靈活的一種方法
        /*View centerView = LayoutInflater.from(this).inflate(R.layout.center_view, null);
        centerView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this,"中間圖示被點選了",Toast.LENGTH_SHORT).show();
            }
        });
        return centerView;*/

        ImageView centerView = new ImageView(this);
        centerView.setImageResource(R.mipmap.ic_launcher_round);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(200,200);
        params.leftMargin = 60;
        params.rightMargin = 60;
        params.bottomMargin = 0;
        centerView.setLayoutParams(params);
        centerView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this,"中間圖示被點選了",Toast.LENGTH_SHORT).show();
            }
        });

        return centerView;
    }
}