开发者头条(三):实现tab与viewpager的联动

学习Ansen的博客,原文:http://blog.csdn.net/lowprofile_coding/article/details/51194577

知识点:

第一:实现首页的3个tab,让tab与viewpager实现联动
第二:轮播图的无限次自动循环滚动。

先看效果图:

这里写图片描述

项目结构图:

这里写图片描述

我们在捋顺一下逻辑:

每一个侧拉页的item对应一个fragment,用这个fragment替换内容页。其中第一个item对应的是首页,首页中又有3个tab,分别对应3个fragment(精选 + 订阅 + 发现 :如果效果一样的话,可以只写一个fragment)。精选:上面是轮播图,下面是listview。

tab与viewpager的联动是怎么实现的?

工具类PageSlidingTab实现的(还有colors.xml等),调用方法 setViewPager(viewPager)实现联动。
下载地址:http://download.csdn.net/detail/ss1168805219/9628964

类中还有一些参数,可以设置下划线 + 分割线 + 底部线 的颜色 高度等。

underLine和indicator的区别?
underline:表示整个下划线,indicator:相当于当前tab对应的underline,只是它有自己的颜色+高度等。
这里写图片描述

tab只有3个,没有充满屏幕宽度,怎么实现充满宽度?

调用PageSlidingTab的方法:setShouldExpand(true),实现充满屏幕宽度。

轮播图的实现

见图:
这里写图片描述

布局的实现

LinearLayout包裹RelativeLayout,里面有ViewPager + TextView + TextView + LinearLayout(指示器)

我把最外层的LiearLayout去掉,TextView与LinearLayout就是水平排列了,再设置above或below无效,不知道为什么?
<?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" >
<!-- 把最外层的linearlayout直接去掉,,marginbottom就失效了,不知道为什么-->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="200dp" >

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager_banner"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <!-- 图片描述文字 -->

        <TextView
            android:id="@+id/tv_desc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="20dp"
            android:layout_marginLeft="10dp"
            android:text="这是图片描述部分" />

        <TextView
            android:id="@+id/tv_ratio"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_marginBottom="20dp"
            android:layout_marginRight="10dp"
            android:text="1/3" />

        <!-- 存放圆点 -->

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <LinearLayout
                android:id="@+id/ll_dots"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_marginBottom="5dp"
                android:gravity="center"
                android:orientation="horizontal" >
            </LinearLayout>
        </RelativeLayout>
    </RelativeLayout>

</LinearLayout>

代码的实现

轮播图先改变viewpager(即图片),再在viewpager的页面切换监听中实现2个textview内容的而转变,和指示器指向下一个。

改变viewpager:

通过handler发送消息。灾handleMessage()中设置viewpager的当期页是当前页+1,并再次发送消息,这样形成死循环。记得要移除消息,放置内存泄漏.

轮播图的详细介绍,请看我的另外2篇博客:轮播图(一):实现ViewPager的无线自动循环 + 轮播图(二):ViewPager实现indicator的滚动

handler.sendEmptyMessageDelayed(0, 2000);
private Handler handler = new Handler(){

    public void handleMessage(android.os.Message msg) {
        if (msg.what == 0) {
            viewPager.setCurrentItem((viewPager.getCurrentItem() + 1) % imagesList.size());
            handler.sendEmptyMessageDelayed(0, 2000);
        }
    }
};
//移除消息,放置内存泄漏
@Override
public void onDestroyView() {
    super.onDestroyView();
    handler.removeMessages(0);
}
怎么改变描述文字 + 指示器的?

在viewpager的监听事件中,设置下一页的数据。
遍历 指示器集合,当viewpager的position与集合的i相同的时候,就显示蓝色,否则是灰色。

@Override
public void onPageSelected(int position) {
    tv_desc.setText(titleList.get(position));
    tv_ratio.setText(1 + position + "/" + titleList.size());
    for (int i = 0; i < dotsList.size(); i++) {
        if (i == position) {
            dotsList.get(i).setBackgroundResource(
                    R.drawable.page_indicator_focused);
        } else {
            dotsList.get(i).setBackgroundResource(
                    R.drawable.page_indicator_unfocused);
        }
    }
}
指示器

跟导航页是一样的,记得设置marginLeft。
注意:开发者头条代码写了2遍,2次都遇到了指示器没显示的情况(我给布局设置了背景色,结果还是不显示),第一次稀里糊涂就解决了,第二次又遇到了。终于被我发现原因了:因为线面的for循环中i < titleList.size(),而这个时候我没没有往titleList中添加数据,这个集合不为null,但是没有数据。size=0,根本没走for循环。

private void initDots() {
    ll_dots.removeAllViews();
    dotsList.clear();
    LayoutParams params = new LinearLayout.LayoutParams(
            LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    params.setMargins(10, 0, 0, 0);
    for (int i = 0; i < titleList.size(); i++) {
        ImageView iv = new ImageView(context);
        if (i == 0) {
            iv.setBackgroundResource(R.drawable.page_indicator_focused);
        } else {
            iv.setBackgroundResource(R.drawable.page_indicator_unfocused);
        }

        ll_dots.addView(iv, params);
        dotsList.add(iv);
    }
}

完成的代码是

首页:HomeFragment.java

package com.cqc.developerheadlinecqc.fragment;

import java.util.ArrayList;
import java.util.List;

import com.cqc.developerheadlinecqc.R;
import com.cqc.developerheadlinecqc.adapter.HomeFragmentPagerAdapter;
import com.cqc.developerheadlinecqc.fragment.home.Frag1;
import com.cqc.developerheadlinecqc.fragment.home.Frag2;
import com.cqc.developerheadlinecqc.fragment.home.Frag3;
import com.cqc.developerheadlinecqc.view.PagerSlidingTab;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class HomeFragment extends Fragment {

    private Context context;
    private View view;
    private PagerSlidingTab pagerTab;
    private ViewPager viewPager;
    private List<Fragment> list = new ArrayList<Fragment>();
    private HomeFragmentPagerAdapter adapter;
    private Frag1 frag1;
    private Frag2 frag2;
    private Frag3 frag3;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getActivity();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.frag_home, container,false);
        pagerTab = (PagerSlidingTab) view.findViewById(R.id.pagerTab_home);
        viewPager = (ViewPager) view.findViewById(R.id.viewPager_home);

        initData();
        adapter = new HomeFragmentPagerAdapter(getActivity().getSupportFragmentManager(), list);
        viewPager.setAdapter(adapter);
        viewPager.setCurrentItem(0);
        pagerTab.setShouldExpand(true);//若tab的宽度没有充满屏幕的宽度,则设置true
        pagerTab.setViewPager(viewPager);
        return view;
    }

    private void initData() {
        list.clear();
        frag1 = new Frag1();
        frag2 = new Frag2();
        frag3 = new Frag3();

        list.add(frag1);
        list.add(frag2);
        list.add(frag3);
    }
}

精选:Frag1.java

package com.cqc.developerheadlinecqc.fragment.home;

import java.util.ArrayList;
import java.util.List;

import com.cqc.developerheadlinecqc.R;
import com.cqc.developerheadlinecqc.adapter.Frag1Adapter;
import com.cqc.developerheadlinecqc.adapter.GuildPagerAdapter;
import com.cqc.developerheadlinecqc.bean.Frag1Bean;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ListView;
import android.widget.TextView;

/**
 * @author cqc 精选
 */
public class Frag1 extends Fragment {

    private ListView listView;
    public List<Frag1Bean> list = new ArrayList<Frag1Bean>();
    public List<String> titleList = new ArrayList<String>();
    public List<ImageView> dotsList = new ArrayList<ImageView>();
    public List<ImageView> imagesList = new ArrayList<ImageView>();
    private Context context;
    private View headView;
    private ViewPager viewPager;
    private TextView tv_desc;
    private TextView tv_ratio;
    private LinearLayout ll_dots;
    private Frag1Adapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getActivity();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.frag1, container, false);
        listView = (ListView) view.findViewById(R.id.listView_frag1);
        initData();
        adapter = new Frag1Adapter(getActivity(), list);
        listView.setAdapter(adapter);

        initHeadView();
        handler.sendEmptyMessageDelayed(0, 2000);
        return view;
    }

    private Handler handler = new Handler(){

        public void handleMessage(android.os.Message msg) {
            if (msg.what == 0) {
                viewPager.setCurrentItem((viewPager.getCurrentItem() + 1) % imagesList.size());
                handler.sendEmptyMessageDelayed(0, 2000);
            }
        }
    };
    private void initHeadView() {
        initTitleList();
        initImagesList();

        headView = View.inflate(context, R.layout.layout_banner, null);
        viewPager = (ViewPager) headView.findViewById(R.id.viewpager_banner);
        tv_desc = (TextView) headView.findViewById(R.id.tv_desc);
        tv_ratio = (TextView) headView.findViewById(R.id.tv_ratio);
        ll_dots = (LinearLayout) headView.findViewById(R.id.ll_dots);
        initDots();

        viewPager.setCurrentItem(0);
        GuildPagerAdapter pagerAdapter = new GuildPagerAdapter(context,
                imagesList);
        viewPager.setAdapter(pagerAdapter);
        viewPager.setOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                tv_desc.setText(titleList.get(position));
                tv_ratio.setText(1 + position + "/" + titleList.size());
                for (int i = 0; i < dotsList.size(); i++) {
                    if (i == position) {
                        dotsList.get(i).setBackgroundResource(
                                R.drawable.page_indicator_focused);
                    } else {
                        dotsList.get(i).setBackgroundResource(
                                R.drawable.page_indicator_unfocused);
                    }
                }
            }

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

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });

        listView.addHeaderView(headView);
    }

    private void initDots() {
        ll_dots.removeAllViews();
        dotsList.clear();
        LayoutParams params = new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        params.setMargins(10, 0, 0, 0);
        for (int i = 0; i < titleList.size(); i++) {
            ImageView iv = new ImageView(context);
            if (i == 0) {
                iv.setBackgroundResource(R.drawable.page_indicator_focused);
            } else {
                iv.setBackgroundResource(R.drawable.page_indicator_unfocused);
            }

            ll_dots.addView(iv, params);
            dotsList.add(iv);
        }
    }

    private void initImagesList() {
        imagesList.clear();

        ImageView iv1 = new ImageView(context);
        ImageView iv2 = new ImageView(context);
        ImageView iv3 = new ImageView(context);

        iv1.setBackgroundResource(R.drawable.icon_selected_carousel_one);
        iv2.setBackgroundResource(R.drawable.icon_selected_carousel_two);
        iv3.setBackgroundResource(R.drawable.icon_selected_carousel_three);

        imagesList.add(iv1);
        imagesList.add(iv2);
        imagesList.add(iv3);
    }

    private void initTitleList() {
        titleList.clear();
        titleList.add("这是第一张图的标题");
        titleList.add("这是第二张图的标题");
        titleList.add("这是第三张图的标题");
    }

    private void initData() {
        list.clear();
        for (int i = 0; i < 10; i++) {
            Frag1Bean bean = new Frag1Bean();
            bean.id = i;
            bean.title = "Android开发666";
            bean.likeNumbers = i;
            bean.commentsNumbers = i;
            list.add(bean);
        }
    }

    //移除消息,放置内存泄漏
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        handler.removeMessages(0);
    }

}

源码:http://download.csdn.net/detail/ss1168805219/9628965

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值