zoukankan      html  css  js  c++  java
  • ViewPager+fragment实现类似微信5.0带滚动条的多屏滑动效果

      

      

      转载请注明出处。

      在本人开发第一个安卓应用的时候就想到多屏滑动的界面(类似于微信5.0的滑动界面,已经流行了很长一段时间),鉴于知识有限,变依靠Tabhos实现了这种效果。思路是:监听并计算滑动距离,切换Tabhost。你可能已经想到了,没错,效果特别差,Tabhost切换仅仅是刷了一下页面而已,什么也没做。后来在网上搜到,导入(现在新建项目都是默认导入)android-support-v4.jar实现里面的ViewPager就行了。

      在Activity里面建立一个ViewPager,然后将我们需要的视图添加到里面就行了。当然最好的方法是ViewPager+Fragment去实现。Fragment类似于Activity,有自己的生命周期。

    Fragment(想要具体了解就去谷歌查询API文档)

      

      

      以下为正文:

    项目文件:

      

        PagerScrollerActivity和TitleIndicator为此项目的核心功能。

    PagerScrollerActivity是就是一个继承了FragmentActivity抽象的类,实现了项目具体功能(管理TitleIndicator)

      关键代码:

        private void initView() throws IndexOutOfBoundsException, NullPointerException {
            setTabsAndAdapter();    //抽象方法,用于实例化Fragment页面以及标题栏
    
            viewPager = (ViewPager) findViewById(R.id.vPager);
            // 设置viewpager内部页面之间的间距
            viewPager.setPageMargin(getResources().getDimensionPixelSize(R.dimen.fragment_viewpager_margin));
            // 设置viewpager内部页面间距的drawable
            viewPager.setPageMarginDrawable(color.myblue);
            
            viewPager.setAdapter(adapter);
            
            //必须让viewPager设置此OnPageChangeListener的实现类,才能对滑动和页面状态监听
            viewPager.setOnPageChangeListener(this);
    
            title = (TitleIndicator) findViewById(R.id.title);
            title.init(tabs, viewPager);
            }
    
        }
    

     PagerScrollerActivity实现 onPageScrolled(int position, float positionOffset, int positionOffsetPixels)用于监听滚动过程,以实现标题栏的实时滚动。

        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        //title 为 TitleIndicator的实例 title.onScroll((viewPager.getWidth() + viewPager.getPageMargin()) * position + positionOffsetPixels);       
         //读者可在纸上画出多个页面的示意图,自己进行计算便能得出这个结果(将坐标想象成所有页面以及变局的总和) }

      

    TitleIndicator是标题栏,数据来自List<TabInfo> tabs,实现实时滚动游标以及点击子标题切换到页面

    先贴上TabInfo的关键代码

    public class TabInfo {
      
      //用于获取到子标题的布局内容,需要的话可以添加ImageView. public View getTab(LayoutInflater inflater, ViewGroup root) { tab = inflater.inflate(R.layout.tab_item, root, false); tv = (TextView) tab.findViewById(R.id.tab_name); tv.setText(name); tab.setId(id); return tab; } }

     TitleIndicator的初始化操作

      public void init(List<TabInfo> tabs, ViewPager viewPager) {
            this.viewPager = viewPager;
            setWillNotDraw(false);// 调用invalidate()时强制调用onDraw()方法
            
        totalTabs = tabs.size(); // 设置标题的每一个Tab的位置属性 for (int i = 0; i < totalTabs; i++) { View view = tabs.get(i).getTab(inflater, this); LinearLayout.LayoutParams lP = (LinearLayout.LayoutParams) view.getLayoutParams(); lP.gravity = Gravity.CENTER_VERTICAL; view.setOnClickListener(this); addView(view); } setCurrentTab(currentTab); }

      TitleIndicator的关键代码,用于重绘游标

        protected void onDraw(Canvas canvas) {
            // TODO Auto-generated method stub
            super.onDraw(canvas);
    
            if (!initialize) {
                initTab(canvas);
            }
    
            float scroll_x = 0;
            if (totalTabs != 0) {
                // 计算滚动条实际滚动距离
                scroll_x = (currentLocationlX - ((currentTab) * (mWidth + viewPager.getPageMargin()))) / totalTabs;
            } else {
                scroll_x = currentLocationlX;
            }
    
            cursorPath.rewind();// 清楚之前的路径状态
    
            float left_x = currentTab * cursorWidth + scroll_x;
            float right_x = (currentTab + 1) * cursorWidth + scroll_x;
            float top_y = mHeight - cursorHeight - 2;
            float bottom_y = mHeight - 2;
    
            cursorPath.moveTo(left_x, top_y); // 移动到基点到左上角
            cursorPath.lineTo(right_x, top_y); // 画线:基点到右上角
            cursorPath.lineTo(right_x, bottom_y);// 基点到右下角
            cursorPath.lineTo(left_x, bottom_y);// 基点到左下角
            cursorPath.close();
            canvas.drawPath(cursorPath, paint);
            initialize = true;
        }
    

      设置当前显示的页面

        public void setCurrentTab(int i) {
            // 清除旧Tab的文字状态
            View view = getChildAt(currentTab);
            view.setSelected(false);
    
            currentTab = i;
            // 设置新Tab的文字状态
            view = getChildAt(currentTab);
            view.setSelected(true);
            invalidate();
    
            if (viewPager.getCurrentItem() != i) viewPager.setCurrentItem(i);
    
        }
    

     源代码下载

      注:转载请注明出处。  

      大神就不要看这么渣的文章了,新手看看就还行。

      本人在网上找了许多demo。后来发现几乎都是同一个大神的文章(http://blog.csdn.net/singwhatiwanna/article/details/17201587),这位大神的demo功能实现非常完善,但本人完全是安卓(java)新手,里面核心代码能够看懂,但是许多细节的不是很清楚。在读懂这个demo的代码后,自己尝试着写一个类似的demo(几乎是一样的,只是功能简单些,对于我这种安卓新手来说比较容易读懂的)。

  • 相关阅读:
    电子辅助的个体化严密控制策略比常规方法更有效地帮助早期RA实现全面控制病情[EULAR2015_THU0122]
    超声和免疫学指标的特征能否反映RA临床缓解的表型?[EULAR2015_THU0121]
    依那西普减量维持过程中RA病人自报病情复发可能预示未来放射学进展[EULAR2015_SAT0147]
    RETRO研究: 持续缓解的RA患者的减量维持方案[EULAR2015_SAT0056]
    OPTIRRA研究: TNF拮抗剂维持期优化减量方案[EULAR2015_SAT0150]
    与时俱进的治疗策略不断提高RA无药缓解机会[EULAR2015_SAT0058]
    雷公藤多甙治疗类风湿关节炎遭质疑
    我的博客今天2岁203天了,我领取了先锋博主徽章
    MyEclipse中最常用的快捷键大全
    MyEclipse无法打开jsp文件(打开是空白的),但是可以打开java文件
  • 原文地址:https://www.cnblogs.com/jiayuqiu/p/3652362.html
Copyright © 2011-2022 走看看