项目地址:https://github.com/blanks1314/sysnc_android
基于公司SDK做的一个支付集成demo,仅以此记录过程中用到的一些技术,望与君共勉之!
效果图:
首先先介绍首页底部导航栏与顶部导航栏+中间viewpager的实现:
借鉴该编博客:http://blog.csdn.net/maosidiaoxian/article/details/38864679 (其他相关接口,和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监听,实现了滑动时改变顶部导航栏的标题。