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

来源:互联网 发布:比较矩阵的相似度 编辑:程序博客网 时间:2024/05/07 03:32

学习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

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

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);        }    }};
//移除消息,放置内存泄漏@Overridepublic void onDestroyView() {    super.onDestroyView();    handler.removeMessages(0);}

怎么改变描述文字 + 指示器的?

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

@Overridepublic 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