您的位置:首页 > 移动开发 > Android开发

底部导航栏(自定义View+ViewPager实现) android项目详解

2015-05-06 11:09 871 查看
项目地址:https://github.com/blanks1314/sysnc_android

基于公司SDK做的一个支付集成demo,仅以此记录过程中用到的一些技术,望与君共勉之!

效果图:









首先先介绍首页底部导航栏与顶部导航栏+中间viewpager的实现:

借鉴该编博客:/article/1375989.html (其他相关接口,和style请阅读该篇博客,本文主要实现的是底部导航、中间viewpager和顶部菜单的联动)快速实现底部菜单加上顶部导航栏,加上一些自己的定制,具体参考以下代码

以下是IconTabPageIndicator类:

package com.wosai.upaydemo.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.wosai.upaydemo.R;

public class IconTabPageIndicator extends LinearLayout implements PageIndicator {
/**
* Title text used when no title is provided by the adapter.
*/
private static final CharSequence EMPTY_TITLE = "";

private String[] mTitles;
private TextView mView;

/**
* Interface for a callback when the selected tab has been reselected.
*/
public interface OnTabReselectedListener {
/**
* Callback when the selected tab has been reselected.
*
* @param position
*            Position of the current center item.
*/
void onTabReselected(int position);
}

private Runnable mTabSelector;

private final View.OnClickListener mTabClickListener = new View.OnClickListener() {
public void onClick(View view) {
TabView tabView = (TabView) view;
final int oldSelected = mViewPager.getCurrentItem();
final int newSelected = tabView.getIndex();
mViewPager.setCurrentItem(newSelected, false);
if (oldSelected == newSelected && mTabReselectedListener != null) {
mTabReselectedListener.onTabReselected(newSelected);
}
if (mTitles.length > 0) {
if (mTitles.length == mViewPager.getAdapter().getCount()) {
mView.setText(mTitles[newSelected]);
} else {
throw new RuntimeException(
"lengthException:titles length != viewpager child count,Please check your title length of an array and viewpager child count the length!");
}
}
}
};

private final LinearLayout mTabLayout;

private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;

private int mSelectedTabIndex;

private OnTabReselectedListener mTabReselectedListener;

private int mTabWidth;

public IconTabPageIndicator(Context context) {
this(context, null);
}

@SuppressLint("NewApi")
public IconTabPageIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
setHorizontalScrollBarEnabled(false);

mTabLayout = new LinearLayout(context, null, R.attr.tabPageIndicator);
addView(mTabLayout, new ViewGroup.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}

public void setOnTabReselectedListener(OnTabReselectedListener listener) {
mTabReselectedListener = listener;
}

@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthMode = View.MeasureSpec.getMode(widthMeasureSpec);
final boolean lockedExpanded = widthMode == View.MeasureSpec.EXACTLY;

final int childCount = mTabLayout.getChildCount();

if (childCount > 1
&& (widthMode == MeasureSpec.EXACTLY || widthMode == MeasureSpec.AT_MOST)) {
mTabWidth = MeasureSpec.getSize(widthMeasureSpec) / childCount;
} else {
mTabWidth = -1;
}

final int oldWidth = getMeasuredWidth();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int newWidth = getMeasuredWidth();

if (lockedExpanded && oldWidth != newWidth) {
// Recenter the tab display if we're at a new (scrollable) size.
setCurrentItem(mSelectedTabIndex);
}
}

private void animateToTab(final int position) {
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
mTabSelector = new Runnable() {
public void run() {
mTabSelector = null;
}
};
post(mTabSelector);
}

@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
if (mTabSelector != null) {
// Re-post the selector we saved
post(mTabSelector);
}
}

@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mTabSelector != null) {
removeCallbacks(mTabSelector);
}
}

private void addTab(int index, CharSequence text, int iconResId) {
final TabView tabView = new TabView(getContext());
tabView.mIndex = index;
tabView.setOnClickListener(mTabClickListener);
tabView.setText(text);

if (iconResId > 0) {
tabView.setIcon(iconResId);
}

mTabLayout.addView(tabView, new LinearLayout.LayoutParams(0,
LayoutParams.MATCH_PARENT, 1));
}

@Override
public void onPageScrollStateChanged(int arg0) {
if (mListener != null) {
mListener.onPageScrollStateChanged(arg0);
}
}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
if (mListener != null) {
mListener.onPageScrolled(arg0, arg1, arg2);
}
}

@Override
public void onPageSelected(int arg0) {
setCurrentItem(arg0);
if (mListener != null) {
mListener.onPageSelected(arg0);
}
}

@Override
public void setViewPager(ViewPager view) {
if (mViewPager == view) {
return;
}
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(null);
}
final PagerAdapter adapter = view.getAdapter();
if (adapter == null) {
throw new IllegalStateException(
"ViewPager does not have adapter instance.");
}
mViewPager = view;
view.setOnPageChangeListener(this);
notifyDataSetChanged();
}

public void notifyDataSetChanged() {
mTabLayout.removeAllViews();
PagerAdapter adapter = mViewPager.getAdapter();
IconPagerAdapter iconAdapter = null;
if (adapter instanceof IconPagerAdapter) {
iconAdapter = (IconPagerAdapter) adapter;
}
final int count = adapter.getCount();
for (int i = 0; i < count; i++) {
CharSequence title = adapter.getPageTitle(i);
if (title == null) {
title = EMPTY_TITLE;
}
int iconResId = 0;
if (iconAdapter != null) {
iconResId = iconAdapter.getIconResId(i);
}
addTab(i, title, iconResId);
}
if (mSelectedTabIndex > count) {
mSelectedTabIndex = count - 1;
}
setCurrentItem(mSelectedTabIndex);
requestLayout();
}

@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}

@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mSelectedTabIndex = item;
mViewPager.setCurrentItem(item, false);

final int tabCount = mTabLayout.getChildCount();
for (int i = 0; i < tabCount; i++) {
final View child = mTabLayout.getChildAt(i);
final boolean isSelected = (i == item);
child.setSelected(isSelected);
if (isSelected) {
animateToTab(item);
}
}
}

@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}

public void setTitles(String[] mTitles, TextView v) {
this.mTitles = mTitles;
this.mView = v;
}

@SuppressLint("NewApi")
private class TabView extends LinearLayout {
private int mIndex;
private ImageView mImageView;
private TextView mTextView;

public TabView(Context context) {
super(context, null, R.attr.tabView);
View view = View.inflate(context, R.layout.tab_view, null);
mImageView = (ImageView) view.findViewById(R.id.tab_image);
mTextView = (TextView) view.findViewById(R.id.tab_text);
this.addView(view);
}

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

// Re-measure if we went beyond our maximum size.
if (mTabWidth > 0) {
super.onMeasure(MeasureSpec.makeMeasureSpec(mTabWidth,
MeasureSpec.EXACTLY), heightMeasureSpec);
}
}

public void setText(CharSequence text) {
mTextView.setText(text);
}

public void setIcon(int resId) {
if (resId > 0) {
mImageView.setImageResource(resId);
}
}

public int getIndex() {
return mIndex;
}
}
}


修改的地方

这里主要是限制传入标题时,标题数量必须与页面数量,以及底部按钮数量相符,否则会抛出自己构建的RuntimeException,

if (mTitles.length > 0) {
if (mTitles.length == mViewPager.getAdapter().getCount()) {
mView.setText(mTitles[newSelected]);
} else {
throw new RuntimeException(
"lengthException:titles length != viewpager child count,Please check your title length of an array and viewpager child count the length!");
}
}


为了实现点击底部button同步改变顶部导航栏的标题:我给IconTabPageIndicator类添加了设置标题控件(暂时只支持传入TextView,欢迎大家fork项目下来,修改的更加灵活,只是提供一种思路,实现底部导航和顶部菜单的联动,其他需求可以根据自己实际情况定制)和标题名称的接口:

public void setTitles(String[] mTitles, TextView v) {
this.mTitles = mTitles;
this.mView = v;
}


具体使用方法:

package com.wosai.upaydemo;

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

import android.app.Dialog;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.widget.TextView;

import cn.wosai.upay.OrderInfo;

import com.wosai.upaydemo.utils.ViewUtil;
import com.wosai.upaydemo.widget.BaseFragment;
import com.wosai.upaydemo.widget.FragmentAdapter;
import com.wosai.upaydemo.widget.IconTabPageIndicator;

public class HomeActivity extends FragmentActivity {

private ViewPager mViewPager;
private IconTabPageIndicator mIndicator;
private TextView textTitle;
private List<BaseFragment> fragments;

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

/**
* 初始化界面
*/
private void initView() {
mViewPager = (ViewPager) findViewById(R.id.vp_content);
mIndicator = (IconTabPageIndicator) findViewById(R.id.indicator);
textTitle = (TextView) findViewById(R.id.tv_title);
FragmentAdapter adapter = new FragmentAdapter(initFragment(),
getSupportFragmentManager());
mViewPager.setAdapter(adapter);
mIndicator.setViewPager(mViewPager);
mIndicator.setTitles(new String[] { "设置", "银联支付", "支付宝支付", "微信支付",
"交易记录" }, textTitle);
mIndicator.setOnPageChangeListener(new OnPageChangeListener() {

@Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub

}

@Override
public void onPageScrollStateChanged(int index) {
// TODO Auto-generated method stub
switch (mViewPager.getCurrentItem()) {
case 0:
textTitle.setText("设置");
break;
case 1:
textTitle.setText("银联支付");
break;
case 2:
textTitle.setText("支付宝支付");
break;
case 3:
textTitle.setText("微信支付");
break;
case 4:
textTitle.setText("交易记录");
break;

}
}
});

}

private List<BaseFragment> initFragment() {

fragments = new ArrayList<BaseFragment>();

BaseFragment settingFragment = new SettingFragment();
settingFragment.setTitle("设置");
settingFragment.setIconId(R.drawable.setting);
fragments.add(settingFragment);

BaseFragment unionFragment = new LakalaFragment();
unionFragment.setTitle("银联");
unionFragment.setIconId(R.drawable.union_pay);
fragments.add(unionFragment);

BaseFragment alipayFragment = new AlipayFragment();
alipayFragment.setTitle("Alipay");
alipayFragment.setIconId(R.drawable.alipay);
fragments.add(alipayFragment);

BaseFragment wexinFragment = new WexinFragment();
wexinFragment.setTitle("微信");
wexinFragment.setIconId(R.drawable.wechat);
fragments.add(wexinFragment);

BaseFragment recordFragment = new RecordFragment();
recordFragment.setTitle("记录");
recordFragment.setIconId(R.drawable.history);
fragments.add(recordFragment);

return fragments;

}

public interface IGetData {
boolean checkData();
OrderInfo getOrderInfo();
}

public SettingFragment getIGetData(){
return (SettingFragment) fragments.get(0);

}
}


该类中的viewpager监听,实现了滑动时改变顶部导航栏的标题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐