Android快速開發02之仿京東底部Tab
阿新 • • 發佈:2019-02-03
自上一篇介紹了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;
}
}