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

Posted 星辰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

以上是关于Android ViewPager+HorizontalScrollView实现标题栏滑动(腾讯新闻)的主要内容,如果未能解决你的问题,请参考以下文章

android 内部viewpager添加点击事件之后不能滑动了

Android-ViewPager2

Android - ViewPager

android viewpager滑动与slidingpanelayout冲突怎么解决

android之ViewPager介绍

Android 中ViewPager练习