Android ViewPager+HorizontalScrollView实现标题栏滑动(腾讯新闻)

1) ViewPager提供了左右滑动切换页面的方法,但是它所提供的标题只是无语,估计没有真正的项目会照搬拿过来;并且它只能一页一页滑,我想直接查看最后一页要滑半天;

2) 看了腾讯新闻客户端感觉体验很好,所以就仿着写了,因为只是做个demo供大家交流也是给自己做个笔记,所以功能实现就行demo比较简单;

3) 有兴趣的可以在demo的基础拓展,如果哪里写得不好还望大家多多赐教、一起交流

4) 直接上主要代码,所以注释都写在代码里,最后会给工程包。(PS是在AS环境下生成的)

先放个效果图:

MainActivity.java

package qi.demo;

import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;

import qi.demo.adapter.MyViewPagerAdapter;

public class MainActivity extends FragmentActivity implements ViewPager.OnPageChangeListener{

    private MainActivity mActivity;
    private ViewPager viewPager;
    private HorizontalScrollView scrollView;
    private LinearLayout titleLayout;
    private ArrayList<Integer> moveToList;          //viewPager滑动时标题栏跟随滑动距离
    private int mTitleMargin;                       //每个标题间的间隔

    private ArrayList<Fragment> fragmentsList;      //viewPager加载类
    private ArrayList<TextView> textViewList;       //标题控件集合
    private ArrayList<String> titleList;            //标题文字集合
    private TestFragment fragment;
    private MyViewPagerAdapter mAdapter;

    private int currentPos;                         //现在显示的是第几页
    private String[] strList = new String[]{"物业服务", "教育", "医疗卫生", "劳动保障", "交通出行", "投资服务", "关于左邻右里"};
    private int[] idList = new int[]{0, 1, 2, 3, 4, 5, 6};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mActivity = this;
        mTitleMargin = dip2px(this, 10);
        initView();
        initData();
    }

    private void initView(){
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        viewPager.setOnPageChangeListener(mActivity);
        scrollView = (HorizontalScrollView) findViewById(R.id.scrollView);
        titleLayout = (LinearLayout) findViewById(R.id.titleLayout);
    }

    /**
     *  1)初始化viewPager
     *  2)设置默认的Fragment
     */
    private void initData(){
        fragmentsList = new ArrayList<>();
        titleList = new ArrayList<>();
        textViewList = new ArrayList<>();
        moveToList = new ArrayList<>();
        mAdapter = new MyViewPagerAdapter(getSupportFragmentManager());
        for(int i=0; i<strList.length; i++){
            titleList.add(strList[i]);
            fragment = new TestFragment(mActivity, idList[i]);
            fragmentsList.add(fragment);
            addTitleLayout(titleList.get(i), idList[i]);
        }
        mAdapter.setData(fragmentsList);
        viewPager.setAdapter(mAdapter);
        viewPager.setOffscreenPageLimit(1);
        textViewList.get(0).setTextColor(Color.rgb(255, 0, 0));
        currentPos = 0;
    }

    /**
     * 添加标题栏
     * @param title     标题名称
     * @param position  标题索引
     */
    private void addTitleLayout(String title, int position){
        final TextView textView = (TextView) getLayoutInflater().inflate(R.layout.title, null);
        textView.setText(title);
        textView.setTag(position);
        textView.setOnClickListener(new posOnClickListener());
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        params.leftMargin = dip2px(mActivity, mTitleMargin);
        params.rightMargin = dip2px(mActivity, mTitleMargin);
        titleLayout.addView(textView, params);
        textViewList.add(textView);
        int width;
        //如果是第一个标题则不设滑动距离
        if(position==0){
            width = 0;
            moveToList.add(width);
        }
        //第N个标题的滑动距离是上一个标题的宽度加上标题之间的间隔,这样的话滑动viewPager的时候保证当前标题栏在最左侧
        else{
            int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            textViewList.get(position-1).measure(w, h);
            width = textViewList.get(position-1).getMeasuredWidth() + mTitleMargin*4;
            moveToList.add(width+moveToList.get(moveToList.size()-1));
        }
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    /**
     * 滑动viewPager
     */
    @Override
    public void onPageSelected(int position) {
        textViewList.get(currentPos).setTextColor(Color.rgb(0, 0, 0));    //将之前的标题栏颜色变回来
        textViewList.get(position).setTextColor(Color.rgb(255, 0, 0));    //将当前标题栏变色
        currentPos = position;                                            //设置当前索引
        scrollView.scrollTo((int) moveToList.get(position), 0);           //标题栏跟随viewPager滑动
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }

    /**
     *  点击标题栏
     */
    class posOnClickListener implements View.OnClickListener{
        @Override
        public void onClick(View view) {
            //点击的是当前标题什么都不做
            if((int)view.getTag()==currentPos){
                return;
            }
            //标题栏变色且设置viewPager
            textViewList.get(currentPos).setTextColor(Color.rgb(0, 0, 0));
            currentPos = (int) view.getTag();
            textViewList.get(currentPos).setTextColor(Color.rgb(255, 0, 0));
            viewPager.setCurrentItem(currentPos);
        }
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

}

MyViewPagerAdapter.java

public class MyViewPagerAdapter extends FragmentPagerAdapter {

    private ArrayList<Fragment> fragmentList;

    public MyViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    public void setData(ArrayList<Fragment> fragmentList){
        this.fragmentList = fragmentList;
    }

    @Override
    public Fragment getItem(int arg0) {
        return fragmentList.get(arg0);
    }

    @Override
    public int getCount() {
        return fragmentList.size();
    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <HorizontalScrollView
        android:id="@+id/scrollView"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:scrollbars="none"
        android:background="#FFFFFF">
        <LinearLayout
            android:id="@+id/titleLayout"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:orientation="horizontal"/>
    </HorizontalScrollView>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <android.support.v4.view.PagerTabStrip
            android:id="@+id/pagerTabStrip"
            android:layout_width="0dp"
            android:layout_height="0dp"/>
    </android.support.v4.view.ViewPager>

</LinearLayout>

demo下载地址:http://download.csdn.net/detail/qy7941237/9344763

原文地址:https://www.cnblogs.com/zhujiabin/p/8202686.html

时间: 2024-10-07 15:15:50

Android ViewPager+HorizontalScrollView实现标题栏滑动(腾讯新闻)的相关文章

Android ViewPager和SlidingPaneLayout的滑动事件冲突处理方法(转载)

最近在做一个项目需要用到ViewPager加载广告图,布局中需要侧滑,用了android V4包里的SlidingPaneLayout控件(该控件在旧的v4包里面没有,需要更新v4包),项目中使用的时候,发现在滑动中ViewPager和SlidingPaneLayout滑动冲突了,当手指从左向右滑动时,ViewPager的滑动事件被SlidingPaneLayout屏蔽了,只能执行SlidingPaneLayout的事件,而从右往左滑时,则正常. 国内找了一些资料,发现不是特别好,最后还是靠VP

Android 自定义 HorizontalScrollView 打造再多图片(控件)也不怕 OOM 的横向滑动效果

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38140505 自从Gallery被谷歌废弃以后,Google推荐使用ViewPager和HorizontalScrollView来实现Gallery的效果.的确HorizontalScrollView可以实现Gallery的效果,但是HorizontalScrollView存在一个很大的问题,如果你仅是用来展示少量的图片,应该是没问题的,但是如果我希望HorizontalScr

Android 实例讲解HorizontalScrollView实现左右滑动

本博文主要讲解怎么使用HorizontalScrollView实现左右滑动的效果. HorizontalScrollView实际上是一个FrameLayout ,一般通过只放置一个LinearLayout子控件.如果要使其添加其他的控件,就使用LinearLayout子控件来添加其他的控件,最后达到丰富其内容的效果.其中,LinearLayout设置的orientation布局为Horizontal.HorizontalScrollView不可以和ListView同时用,因为ListView有自

android ViewPager左右滑动翻页,并可以删除page

首先新建一个Activity,继承FragmentActivity. 初始化一个Fragment的List集合,用于像FragmentStatePagerAdapter填充数据,而ViewPager由FragmentStatePagerAdapter的实例进行初始化.和ListView一样,Fragment的List集合的数据变了,就通知FragmentStatePagerAdapter进行界面刷新. ArrayList<Fragment> fragments =new ArrayList&l

Android viewpager 嵌套 viewpager滑动 点击事件冲突解决方案

为了解决这个问题.可以自定义viewpager,然后在里面监听首饰,自定义点击事件 package com.hpuvoice.view; import android.content.Context; import android.graphics.PointF; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.view.GestureDetector; impo

Android使用ViewPager实现左右循环滑动及轮播效果

ViewPager是一个常用的android组件,不过通常我们使用ViewPager的时候不能实现左右无限循环滑动,在滑到边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其他页面的信息. 为此我查阅了网络上现有的一些关于实现这样效果的例子,但都不是很满意,经过反复实验,在这里总结并分享给大家,希望能有所帮助. 循环滑动效果的实现:PagerAdap

Android重写HorizontalScrollView模仿ViewPager效果

Android提供的ViewPager类太复杂,有时候没有必要使用,所以重写一个HorizontalScrollView来实现类似的效果,也可以当做Gallery来用 思路很简单,就是重写onTouchEvent事件,在手指抬起或者取消的时候,进行smoothScroll的操作,具体请看代码: 布局文件:activity_test.xml ? 1 2 3 4 5 6 1 <!--?xml version=1.0 encoding=utf-8?-->  2 <com.example.tes

Android实战简易教程-第三十四枪(基于ViewPager和FragmentPagerAdapter实现滑动通用Tab)

上一段时间写过一篇文章<基于ViewPager实现微信页面切换效果> 里面实现了类似微信Tab的页面,但是这种实现方法有个问题,就是以后所有的代码逻辑都必须在MainActivity中实现,这样就造成MainActivity文件非常臃肿,不利于代码管理. 下面我们基于ViewPager和FragmentPagerAdapter实现滑动通用Tab. 布局文件基本和上篇文章一致. 1.top.xml: <?xml version="1.0" encoding="

Android ViewPager实现Tabhost选项卡底部滑块动态滑动过渡

 <Android ViewPager实现Tabhost选项卡底部滑块动态滑动过渡> 之前基于github上的第三方开源控件ViewPagerIndicator的UnderlinePageIndicator(原文链接:http://blog.csdn.net/zhangphil/article/details/44752213),自己写了一个底部带有滑块.且当ViewPager页面切换时候选项卡也随之相应切换,且滑块也随之相应动态滑动效果得控件.但写的太过于紧耦合,不利于复用,所以现在重构