最近项目页面中经常出现诸如下图的控件,如果为每个页面分别写一个将会造成非常多的重复代码,不利于项目的阅读和维护,也会使项目变得非常凌乱。所以,对于这种情况我们可以进行一定的抽取,传入相关数据后自动显示到控件上。
由上图可知,我们需要上面的Tab作为指示,下面是类似轮播图ViewPager。我们需要实现点击Tab切换到相应轮播图页面,同时滚动Page上面的Tab做相应的变化。
此时我们要动态填充上面Tab的内容以及轮播图的内容。所以我把这两块建立了一个组合控件。Tab用一条LinearLayout,下面是ViewPager。同时提供数据接口,分别用于传入Tab和ViewPager内容。
此处Tab分为背景和内容,背景是控件统一的,可以封装在控件内部设置,所以我们要传入文字的相关部分,这里我使用传入TextView。
ViewPager的内容,我们封装在一个Holder中,Holder可以提供显示内容及其数据。
有了这两个内容,我们就可以以适当的方e式将内容分别填充到上面的LinearLayout中和ViewPager中。
主要涉及的问题
- Tab动态加入LinearLayout时布局问题
- Tab的滑动与ViewPager的关联
git
https://git.oschina.net/vonchenchen/MySlidingTabPager.git
private void initView(){
//构造Tab
TextView tab1 = new TextView(MainActivity.this);
tab1.setText("TAB1");
TextView tab2 = new TextView(MainActivity.this);
tab2.setText("TAB2");
TextView tab3 = new TextView(MainActivity.this);
tab3.setText("TAB3");
TextView tab4 = new TextView(MainActivity.this);
tab4.setText("TAB4");
//加入Tab
mMySlidingTabPager.addTab(tab1);
mMySlidingTabPager.addTab(tab2);
mMySlidingTabPager.addTab(tab3);
mMySlidingTabPager.addTab(tab4);
//创建页面holder
ViewHolder1 holder1 = new ViewHolder1();
ViewHolder2 holder2 = new ViewHolder2();
ViewHolder3 holder3 = new ViewHolder3();
ViewHolder4 holder4 = new ViewHolder4();
//加入页面holder
mMySlidingTabPager.addHolder(holder1);
mMySlidingTabPager.addHolder(holder2);
mMySlidingTabPager.addHolder(holder3);
mMySlidingTabPager.addHolder(holder4);
//页面填充 这里就可以显示啦!!!
mMySlidingTabPager.start();
}
/** * 自绘控件封装类 * Created by vonchenchen on 2015/11/3 0003. */
public abstract class BaseWidgetHolder<T> {
protected View mRootView;
public abstract View initView();
public abstract void refreshView(T data);
public BaseWidgetHolder(){
mRootView = initView();
mRootView.setTag(this);
}
public View getRootView(){
return mRootView;
}
}
/** * Created by vonchenchen on 2015/11/19 0019. */
public class MySlidingTabPager extends RelativeLayout{
private Context mCtx;
/** Tab布局 */
private LinearLayout mTabsLayout;
/** ViewPager */
private ViewPager mContentViewPager;
private List<TextView> mTabList;
private List<BaseWidgetHolder> mHolderList;
private MyPagerAdapter mMyPagerAdapter;
private int mRecordPosition = -1;
public MySlidingTabPager(Context context) {
super(context);
this.mCtx = context;
}
public MySlidingTabPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.mCtx = context;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
View.inflate(mCtx, R.layout.layout_slidingtabpager, this);
mTabsLayout = (LinearLayout) findViewById(R.id.ll_tabs);
mContentViewPager = (ViewPager) findViewById(R.id.vp_content);
mTabList = new ArrayList<TextView>();
mHolderList = new ArrayList<BaseWidgetHolder>();
//监听ViewPager滚动
mContentViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//ViewPager滑动 对应Tab选择
updateTab(position, false);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
/** * 添加Tab * @param tab */
public void addTab(TextView tab){
mTabList.add(tab);
}
/** * 添加holder * @param holder */
public void addHolder(BaseWidgetHolder holder){
mHolderList.add(holder);
}
/** * 开启显示 */
public void start(){
initTabView();
initViewPager();
}
private void initTabView(){
//设置Layout参数,用于添加新的Tab
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, dip2px(MyApplication.getContext(), 40));
params.weight = 1;
for(int i=0; i<mTabList.size(); i++){
TextView view = mTabList.get(i);
view.setGravity(Gravity.CENTER);
final int position = i;
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
mContentViewPager.setCurrentItem(position);
updateTab(position, true);
}
});
//将TextView加入到LinearLayout上
mTabsLayout.addView(view, params);
setViewUnSelected(view, i);
}
//初始化默认Tab颜色及其位置
mRecordPosition = 0;
setViewSelectd(mTabList.get(0), 0);
}
private void updateTab(int position, boolean isTouchTab){
if(position != mRecordPosition){
setViewSelectd(mTabList.get(position), position);
}
if(mRecordPosition >= 0 && !isTouchTab){
setViewUnSelected(mTabList.get(mRecordPosition), mRecordPosition);
}
mRecordPosition = position;
}
/** * 当Pager被选择时设置对应Tab的颜色 * @param view * @param position */
private void setViewSelectd(View view, int position){
if(position == 0){
view.setBackgroundResource(R.drawable.shape_detail_rb_left_blue);
}else if(position == mTabList.size()-1){
view.setBackgroundResource(R.drawable.shape_detail_rb_right_blue);
}else{
view.setBackgroundResource(R.drawable.shape_detail_rb_mid_blue);
}
}
/** * 取消Tab的选中颜色 * @param view * @param position */
private void setViewUnSelected(View view, int position){
if(position == 0) {
view.setBackgroundResource(R.drawable.shape_detail_rb_left_white);
}else if(position == mTabList.size()-1){
view.setBackgroundResource(R.drawable.shape_detail_rb_right_white);
}else{
view.setBackgroundResource(R.drawable.shape_detail_rb_mid_white);
}
}
private void initViewPager(){
mMyPagerAdapter = new MyPagerAdapter();
mContentViewPager.setAdapter(mMyPagerAdapter);
}
public class MyPagerAdapter extends PagerAdapter {
@Override
public int getCount() {
return mTabList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(mHolderList.get(position).getRootView());
return mHolderList.get(position).getRootView();
}
}
private int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale);
}
}