自定义ViewPagerIndicator
2016-06-30 16:48
330 查看
下载地址
我的学习视频地址,一起来学习Android…http://edu.csdn.net/course/detail/2741/43164?auto_start=1
http://edu.csdn.net/course/detail/2741/43163
代码下载地址:http://download.csdn.net/detail/zhiyuan0932/9564014
创建构造方法及代码初始化
public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public ViewPagerIndicator(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ViewPagerIndicator(Context context) { super(context); init(); } private void init() { // 获取当前屏幕的宽高 WindowManager windowManager = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); outMetrice = new DisplayMetrics(); windowManager.getDefaultDisplay().getMetrics(outMetrice); // 初始化画笔 paint = new Paint(); paint.setColor(Color.RED); paint.setStrokeWidth(10); }
设置关联的viewPager
/** * 设置相关联的viewPager * * @param viewPager */ public void setViewPager(final ViewPager viewPager) { this.viewPager = viewPager; // 对viewPager设置监听事件 viewPager.setOnPageChangeListener(this); // 创建线性布局 linearLayout = new LinearLayout(getContext()); // 将线性布局添加到当前自定义的HorizontalScrollView中 this.addView(linearLayout); // 获取viewpager的数据适配器,然后获取数据适配器展示的条目的个数 int count = viewPager.getAdapter().getCount(); // 循环遍历 for (int i = 0; i < count; i++) { // 获取当前的title String title = (String) viewPager.getAdapter().getPageTitle(i); // 有多少个Title,就动态的添加多少个TextView final TextView textView = new TextView(getContext()); // 设置线性布局的布局参数 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); // 设置当前的边距值,默认设置为屏幕宽度的1/5 marginValue = outMetrice.widthPixels / 5; params.setMargins(0, 0, marginValue, 5); // 设置TextSize textView.setTextSize(textSize); // 设置TextView的标题 textView.setText(title); if (i == 0) { // 对于初始的textView的颜色 textView.setTextColor(selectedTextColor); // 当textView可见的时候,获取textView的宽度 textView.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { @SuppressWarnings("deprecation") @Override public void onGlobalLayout() { // 初始的textView的宽度定义为索引值为0位置处的索引值 textViewWidth = textView.getWidth(); textView.getViewTreeObserver() .removeGlobalOnLayoutListener(this); // 当获取到textView的宽度时,重新刷新一下界面 postInvalidate(); } }); } else { // 设置textView的未选中的默认字体颜色 textView.setTextColor(unselectedTextColor); } // 将textView添加到线性布局中 linearLayout.addView(textView, params); // 将textView添加到map集合中 tvMap.put(textView, i); // 对textView设置点击事件的监听 textView.setOnClickListener(this); } }
设置相应的监听事件
@Override public void onClick(View v) { // 获取当前的map中的textView的索引值,然后设置viewPager跳转到那个界面上 viewPager.setCurrentItem(tvMap.get(v)); } @Override public void onPageScrollStateChanged(int state) { // 获取当前状态,对于viewPager的状态,并定义到成员 this.state = state; } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { // 计算当前的偏移量,用于绘制顶部的红线或者是图片 int sumWidth = 0; // 循环遍历所有的在该position前的控件,然后计算出当前的位置 for (int i = 0; i < position; i++) { sumWidth = sumWidth + linearLayout.getChildAt(i).getWidth() + marginValue; } // 获取线性布局中的child,然后获取这个textView的宽度 View view = linearLayout.getChildAt(position); int width = view.getWidth(); // 在滑动时将这个宽度赋值给在成员定义的textViewWidth,用于绘制指示线的宽度(这样可以做到文字有多长,指示线就有多长) textViewWidth = width; // 计算出当前指示线的起点位置 偏移的比例*(控件自身宽度+控件的marginRight值)+之前计算出的x坐标 currentX = positionOffset * (width + marginValue) + sumWidth; // 刷新onDraw postInvalidate(); } /** * @param selectTextColor * 选中的字体颜色 * @param normalTextColor * 未选中的字体颜色 * @param textSize * 字体大小 */ public void setTextViewAttr(int selectedTextColor, int unselectedTextColor, int textSize) { this.selectedTextColor = selectedTextColor; this.unselectedTextColor = unselectedTextColor; this.textSize = textSize; } @SuppressLint("NewApi") @Override public void onPageSelected(int position) { // 当滑动到某一页时,让该索引值下的textView颜色变成选中的颜色 for (int i = 0; i < linearLayout.getChildCount(); i++) { TextView tv_title = (TextView) linearLayout.getChildAt(i); if (position == i) { tv_title.setTextColor(selectedTextColor); } else { tv_title.setTextColor(unselectedTextColor); } } }
绘制指示器
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 如果现实indicator显示,就绘制底部的indicator if (isVisible) { // 判断要显示的indicator时什么样式,是颜色样式还是图片样式 if (style == STYLE_COLOR) { // 绘制指示线 canvas.drawLine(currentX, this.getHeight(), currentX + textViewWidth, this.getHeight(), paint); } else if (style == STYLE_DRAWABLE) { // 设置Bitmap左上右下的位置 RectF dst = new RectF(); // 左侧时当前的位置 dst.left = currentX; // 右侧是textView宽度+currentX dst.right = currentX + textViewWidth; // 底部是HorizontalScrollView的高度 dst.bottom = this.getHeight(); // 设置顶部的坐标 dst.top = this.getHeight() * 4.0f / 5; // 绘制图片 canvas.drawBitmap(bitmap, null, dst, paint); } } if (currentX >= outMetrice.widthPixels / 2 && state == ViewPager.SCROLL_STATE_DRAGGING) { // 设置horizontalScrollView滑动到的位置 this.scrollTo((int) (currentX - outMetrice.widthPixels / 2), 0); } else if (currentX < outMetrice.widthPixels / 2 && state == ViewPager.SCROLL_STATE_DRAGGING) { this.scrollTo(0, 0); } }
设置自定义指示器效果
/** * 设置指示线或者指示图标显示或隐藏,默认显示 * * @param isVisible * true代表显示,false代表隐藏 */ public void setIndicatorVisible(boolean isVisible) { this.isVisible = isVisible; } /** * 设置指示器类型 * * @param VIEWSTYLE_COLOR * 单纯的设置指示器颜色 * @param STYLE_DRAWABLE * 可以设置指示器的图标 */ public void setIndicatorStyle(int style) { this.style = style; } /** * 设置指示线的颜色 * * @param indicatorColor */ public void setIndicatorColor(int indicatorColor) { paint.setColor(indicatorColor); } /** * 设置指示线的宽度 * * @param indicatorStrokeWidth */ public void setIndicatorStrokeWidth(int indicatorStrokeWidth) { paint.setStrokeWidth(indicatorStrokeWidth); } /** * 如果indicator展示样式为自定义的图片,需要设置图片,否则不需要设置 * * @param drawableResource * 图片资源 */ public void setIndicatorResource(int drawableResource) { try { bitmap = BitmapFactory.decodeResource(getResources(), drawableResource); if (bitmap == null) { bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.error_tip_btn_pressed); } } catch (Exception e) { Log.i(TAG, "请设置正确图片"); e.printStackTrace(); } } /** * @param selectTextColor * 选中的字体颜色 * @param normalTextColor * 未选中的字体颜色 * @param textSize * 字体大小 */ public void setTextViewAttr(int selectedTextColor, int unselectedTextColor, int textSize) { this.selectedTextColor = selectedTextColor; this.unselectedTextColor = unselectedTextColor; this.textSize = textSize; }
Xml中引用该ViewPagerIndicator
<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:orientation="vertical" > <com.zhiyuan.viewpagerindicator.ViewPagerIndicator android:id="@+id/chsv" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ff0000" android:scrollbars="none" /> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
在代码中可以对ViewPagerIndcator进行设置
public class MainActivity extends FragmentActivity { private ViewPagerIndicator chsv; private ViewPager viewPager; String[] titles = new String[] { "AAAAAA", "BBBBBB", "CCCCCC", "DDDDD", "EEEE", "FFFF", "G", "H", "III", "GGG", "KKKKKK" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 关联布局,实例化控件 chsv = (ViewPagerIndicator) findViewById(R.id.chsv); viewPager = (ViewPager) findViewById(R.id.viewPager); viewPager.setAdapter(new FragmentPagerAdapter( getSupportFragmentManager()) { @Override public int getCount() { return titles.length; } @Override public Fragment getItem(int position) { Fragment instance = TitleFragment.getInstance(titles[position]); return instance; } /** * 设置indicator展示的标题 */ @Override public CharSequence getPageTitle(int position) { return titles[position]; } }); // viewPager和viewPagerIndicator相关联 chsv.setViewPager(viewPager); // 设置TextView属性 chsv.setTextViewAttr(Color.WHITE, Color.BLACK, 30); // 设置指示器颜色 chsv.setIndicatorColor(Color.GRAY); // 设置是否显示指示器 chsv.setIndicatorVisible(true); // 设置指示器是显示自定义图片还是颜色 chsv.setIndicatorStyle(ViewPagerIndicator.STYLE_DRAWABLE); // 设置指示器显示的图片 chsv.setIndicatorResource(R.drawable.error_tip_btn_pressed); } }
自己定义的Fragment展示ViewPager内容
public class TitleFragment extends Fragment { @SuppressLint("NewApi") @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { Bundle arguments = getArguments(); String string = arguments.getString("title", ""); TextView tv = new TextView(getActivity()); tv.setText(string); return tv; } /** * 获取Fragment实例对象 * * @param title * 当前页面展示的内容 * @return Fragment */ public static Fragment getInstance(String title) { TitleFragment titleFragment = new TitleFragment(); Bundle args = new Bundle(); args.putString("title", title); titleFragment.setArguments(args); return titleFragment; } }