自定义ViewPagerIndicator:100行代码实现两种可滑动指示器
来源:互联网 发布:手机加油软件代理 编辑:程序博客网 时间:2024/06/04 19:34
按照惯例先上图,一种是三角形,一种是最常用的下划线
实现思路,主要是在onPageScroll里面进行指示器滑动距离和父容器滑动距离的计算,然后进行滑动,滑动解决了其他就比较简单了。
顶部就是自定义的ViewPagerIndicator,下面就是Fragment+FragmentPagerAdagter
主MainActivity代码,就是常规的ViewPagerIndicator结合Fragment
public class IndicatorActivity extends AppCompatActivity { private ViewPagerIndicator indicator; private ViewPager mViewPager; private List<Fragment> mList = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_indicator); mList.add(TitleFragment.newInstance("标题1")); mList.add(TitleFragment.newInstance("标题2")); mList.add(TitleFragment.newInstance("标题3")); mList.add(TitleFragment.newInstance("标题4")); mList.add(TitleFragment.newInstance("标题5")); mList.add(TitleFragment.newInstance("标题6")); mList.add(TitleFragment.newInstance("标题7")); mList.add(TitleFragment.newInstance("标题8")); mList.add(TitleFragment.newInstance("标题9")); indicator = (ViewPagerIndicator) findViewById(R.id.indicator_activity); indicator.setSelected_indicator(ViewPagerIndicator.LINE);//使用三角形 indicator.selectText(0);//默认选中第一个 mViewPager = (ViewPager) findViewById(R.id.viewpager_indicator); mViewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager(), mList)); mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { indicator.move(position, positionOffset); //position当前fragment,offset滑动值0-1 } @Override public void onPageSelected(int position) { indicator.selectText(position);//textview选中效果 } @Override public void onPageScrollStateChanged(int state) { } }); }}
Fragment里面就一个textview很简洁
public class TitleFragment extends Fragment { private static final String PARAM1 = "param1"; private String mParam1; private Context mContext; private callback mCb; public static TitleFragment newInstance(String text) { TitleFragment fragment = new TitleFragment(); Bundle bundle = new Bundle(); bundle.putString(PARAM1, text); fragment.setArguments(bundle); return fragment; } @Override public void onAttach(Context context) { super.onAttach(context); if (context != null) { mContext = context; if (context instanceof callback) { mCb = (callback) context; } } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { mParam1 = getArguments().getString(PARAM1); } } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { //不写xml文件 TextView textView = new TextView(mContext); textView.setText(mParam1); textView.setGravity(Gravity.CENTER); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); lp.gravity = Gravity.CENTER; textView.setLayoutParams(lp); return textView; } @Override public void onDetach() { super.onDetach(); mCb = null; } public interface callback { void success(String msg); }}
Adapter没什么好说的
public class ViewPagerAdapter extends FragmentPagerAdapter { private List<Fragment> mList = new ArrayList<>(); public ViewPagerAdapter(FragmentManager fm, List<Fragment> mList) { super(fm); this.mList = mList; } @Override public Fragment getItem(int position) { return mList.get(position); } @Override public int getCount() { return mList.size(); }}
主角自定义的ViewPagerIndicator,继承的LinnerLayout,在里面加TextView的方式,加了挺多注释的应该很好理解
public class ViewPagerIndicator extends LinearLayout { private static final String TAG = "ViewPagerIndicator"; public static final int TRIANGLE = 1;//三角形 public static final int LINE = 2;//下划线 public static int selected_indicator = TRIANGLE;//要使用的指示器 private int mScreenWidth;//屏幕宽 private int mTitleWidth;//每个标题宽 private int mTriangleWidth;//三角宽 private int mInitLeftMargin;//初始化的三角x位置 private int mMoveMargin = 0;//计算出来的移动x位置 private int mTriangleY;//三角形底部的位置Y private int mTitleCount = 9;//标题总数 private int mVisibableCount = 3;//一屏显示标题数量 public ViewPagerIndicator(Context context) { this(context, null); } public ViewPagerIndicator(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); mScreenWidth = wm.getDefaultDisplay().getWidth(); //初始化一些指示器的宽高参数 mTitleWidth = mScreenWidth / 3;//默认每个标题占屏幕三分之一宽 mTriangleWidth = mScreenWidth / 3 / 6;//一个三角形底边占每个标题六分之一 mInitLeftMargin = mScreenWidth / 3 / 2 - (mTriangleWidth / 2);//初始化第一次三角在标题下居中 mTriangleY = DensityUtil.dip2px(context, 50);//xml标题栏高50dp Log.d(TAG, mScreenWidth + "-" + mTriangleWidth + "-" + mInitLeftMargin); //获取标题数量 TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ViewPagerIndicator); mTitleCount = array.getInt(R.styleable.ViewPagerIndicator_titleCount, mTitleCount); array.recycle(); //生成标题 for (int i = 0; i < mTitleCount; i++) { TextView textView = new TextView(context); textView.setText("标题" + (i + 1)); textView.setTextColor(getResources().getColor(R.color.titile_text_color)); textView.setGravity(Gravity.CENTER); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(mScreenWidth / mVisibableCount, ViewGroup.LayoutParams.MATCH_PARENT); textView.setLayoutParams(lp); addView(textView); } } //指示器+容器滚动 public void move(int pos, float offset) { if (selected_indicator == TRIANGLE) { mMoveMargin = (int) (mInitLeftMargin + pos * mTitleWidth + (offset * mTitleWidth));//三角形移动 }else if (selected_indicator == LINE) { mMoveMargin = (int) (pos * mTitleWidth + (offset * mTitleWidth));//线移动 } //容器滚动,在一屏倒数第二个才允许 if (pos >= mVisibableCount - 2 && pos < mTitleCount - 2) { scrollTo((int) ((pos - (mVisibableCount - 2)) * mTitleWidth + (mTitleWidth * offset)), 0); } invalidate(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //画三角形画笔 Paint paint = new Paint(); paint.setColor(getResources().getColor(R.color.master_color)); paint.setStyle(Paint.Style.FILL); paint.setStrokeWidth(10.0f);//线宽 if (selected_indicator == TRIANGLE) { if (mMoveMargin == 0) {//不是第一次draw,使用移动的值 mMoveMargin = mInitLeftMargin; } //直角三角形 Path path = new Path(); path.moveTo(mMoveMargin, mTriangleY);//左点 path.lineTo(mMoveMargin + mTriangleWidth, mTriangleY);//右点 path.lineTo(mMoveMargin + (mTriangleWidth / 2), mTriangleY - (mTriangleWidth / 2));//上点 path.close(); canvas.drawPath(path, paint); }else if (selected_indicator == LINE) { canvas.drawLine(mMoveMargin, mTriangleY, mTitleWidth + mMoveMargin, mTriangleY, paint); } } public void setSelected_indicator(int selected_indicator) { this.selected_indicator = selected_indicator; } //选中改变字体颜色 public void selectText(int position) { TextView textView; for (int i = 0; i < mTitleCount; i++) { textView = (TextView) getChildAt(i); if (position == i) { textView.setTextColor(getResources().getColor(R.color.colorAccent)); } else { textView.setTextColor(getResources().getColor(R.color.titile_text_color)); } } }}
代码基本贴完了,就不上传工程了,写了大半天时间,有些问题可能没考虑到,见谅一下,毕竟才一百行,不过麻雀虽小五脏俱全啊。
0 0
- 自定义ViewPagerIndicator:100行代码实现两种可滑动指示器
- ViewPagerIndicator 自定义指示器
- 轻松实现分页指示器 ViewPagerIndicator Android自定义控件
- Android 自定义控件ViewPager 指示器 ViewPagerIndicator
- 自定义页面滑动指示器
- 自定义ViewPagerIndicator---炫酷的导航栏指示器+ViewPager+Fragment
- 使用actionBar,实现ViewPagerIndicator的效果(ViewParger指示器)
- ViewPagerIndicator+viewpager指示器详解
- ViewPagerIndicator(ViewPager指示器)
- ViewPagerIndicator的指示器应用
- viewpagerindicator ViewPager指示器
- ViewPagerIndicator+viewpager指示器详解
- 自定义指示器 快速实现 ViewPager 滑动页卡切换(可用作整个 app上导航)
- RecycleView实现横向带指示器翻页滑动,一行两列自定义布局
- 开源库【ViewPagerIndicator】配合ViewPager使用的圆点指示器,圆点随滑动而移动
- 自定义view实现ViewPager指示器
- DotLoopViewpager两个方法,几行代码实现轮播图,超强自定义的自动轮播的小圆点指示器
- ViewPagerIndicator替换成三角形指示器
- Java时间为什么从1970-01-01 00:00:00 000开始
- postgresql得到时间对应周的周一
- 表单增强与验证——选择框(联动选择框)
- iOS 检查更新
- Python学习笔记 —— 函数
- 自定义ViewPagerIndicator:100行代码实现两种可滑动指示器
- 书架卡顿问题引发的显示类知识梳理&性能检测
- 银行自动存取一体机例题
- 负载平衡问题(最小费用流)
- poj 1321 简单搜索
- 电学发展史
- curl模拟post请求提交
- 万年历程序例题(农历阴历转换)
- Struts2配置拦截器的后缀名