参考资料:慕课网的课程-Android-自定义ViewPager指示器
1、固定tab数量的带有指示器的viewPager,代码下载请点我
2、动态加载tab的带有指示器的viewPager,代码下载请点我
学习笔记:
fragment传递参数
首先在自己的TestFragment中定义一个创建fragment 的方法:
public static TestFragment newInstance(String title){
Bundle bundle = new Bundle();
bundle.putString(TITLE_KEY, title);
TestFragment testFragment = new TestFragment();
//此方法就是把bundle传递出去
testFragment.setArguments(bundle);
return testFragment;
}
上面方法中的参数title就是要传递的数据,你也可以设置成其它的,或多个参数。
然后在onCreateView方法中得到传过来的值:
Bundle bundle = getArguments();
if (bundle != null){
//当传过来的值为空时,就把"cc"赋值给title
title = bundle.getString(TITLE_KEY,"cc");
}
最后在Activity中创建Fragment时,如下:
TestFragment testFragment = TestFragment.newInstance("cc");
就把”cc”传给fragment了。
在自定义ViewGroup时,需要注意的几个方法
1、dispatchDraw(): 这里面时绘制界面的,当我们需要手动绘制图形时,就可以重写此方法,如下:
/**
* 此方法中绘制三角形
* @param canvas
*/
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.save();
//开始绘制
//平移到开始绘制的地方
canvas.translate(initTranslateX + translateX, getHeight());
//根据path中的路径,绘制图形
canvas.drawPath(path, paint);
canvas.restore();
super.dispatchDraw(canvas);
}
2、onSizeChanged()
触发时机:
当界面中的控件测量完,view的大小确定后,就会调用此方法;
当view的大小改变时,就会调用此方法;
当绘制(onDraw)时,就会掉用此方法;
作用:
我们可以在onSizeChanged() 方法中初始化一些view的宽高,如下:
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
triangleWidth = (int) (w / visibleTabCount * TRIANGLE_SCALE);
//控制三角形的底边宽不能超过最大值
triangleWidth = Math.min(triangleWidth,TRIANGLE_MAX_WIDTH);
initTranslateX = w / visibleTabCount / 2 - triangleWidth / 2;
triangleHeight = triangleWidth / 2;
initTriangle();
}
3、onFinishInflate(): 当xml文件加载完成后,就会掉用此方法;
在此方法中我们可以设置一些控件的宽高,如下:
/**
* 当xml文件加载完成后调用
*/
@Override
protected void onFinishInflate() {
super.onFinishInflate();
int count = getChildCount();
if (count == 0) {
return;
}
for (int i = 0; i < count; i++) {
View view = getChildAt(i);
LayoutParams params = (LayoutParams) view.getLayoutParams();
params.weight = 0;
params.width = getScreenWidth() / visibleTabCount;
view.setLayoutParams(params);
}
setTitleOnClickEvent();
}
4、当我们在自定义view中,占用了某个view的监听器后,需要重写一个监听器,供用户使用,如下:
/**
* 将ViewPager的滑动监听封装在指示器的容器中
* 只要调用此方法就可以实现带指示器的ViewPager 了
*
* @param vp
* @param pos 当前的ViewPager中子View 的位置
*/
public void setViewPager(ViewPager vp, final int pos) {
viewPager = vp;
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
scroll(position, positionOffset);
if (listener != null) {
listener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
if (listener != null) {
listener.onPageSelected(position);
}
//被选中时
selectedTextView(position);
}
@Override
public void onPageScrollStateChanged(int state) {
if (listener != null) {
listener.onPageScrollStateChanged(state);
}
}
});
//初始化
viewPager.setCurrentItem(pos);
selectedTextView(pos);
}
我们在自定义的viewGroup中使用了viewPager的滑动监听器,那我门就要自定义了监听器供用户使用,如下:
//此指示器对应的ViewPager
private ViewPager viewPager;
//ViewPager滑动的监听器
private PagerOnChangeListener listener;
/**
* 给外部提供设置ViewPager监听器的方法
*
* @param l
*/
public void setPagerOnChangeListener(PagerOnChangeListener l) {
listener = l;
}
/**
* 定义此接口,是为了给用户提供viewPager的滑动监听
* 当用户需要监听时,就可实现此接口
* 这三个方法与viewPager监听器中的那三个方法一一对应
*/
public interface PagerOnChangeListener {
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
public void onPageSelected(int position);
public void onPageScrollStateChanged(int state);
}